前言:上次与大家分享了SSH框架之Struts的知识,今天就接着之前的分享,今天要分享的知识是Ognl
码字不易,点个赞
转载请说明!
开发工具:eclipse
目录
OGNL是什么?
一、明确目标
1、弄清楚之前遗留的问题(user中的uname属性有值,而Demo1Action中的uanme属性没有值?) 2、Struts的优先级
二、Struts的优先级
三、Ognl的特点
1、值栈是先进后出的特点
2、计数是从上至下的
四、解决上次的问题(user中的uname属性有值,而Demo1Action中的uanme属性没有值)
OGNL是什么?
OGNL的全称是Object Graph Navigation Language(对象图导航语言)
ognlContext(ognl上下文)其实就是Map(教室、老师、学生)
Map:教室
OgnlContext = 根对象(1)+ 非根对象(N)
老师: 根对象 1
学生 :非根对象 n
非根对象要通过"#key"访问,根对象可以省略"#key"
一、明确目标 1、弄清楚之前遗留的问题(user中的uname属性有值,而Demo1Action中的uanme属性没有值?)2、Struts的优先级
情景再现
在之前的demo1action界面中加一个uname属性,并且生成get和set方法。在demo1中再写set方法传值的代码
Demo1Action界面
package com.hpw.one.web; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.ServletResponseAware; import com.hpw.one.entity.User; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; public class Demo1Action extends ActionSupport implements ModelDriven,ServletRequestAware,ServletResponseAware{ private HttpServletRequest req; private HttpServletResponse resp; private User user1 = new User(); private String uname; private String sex; private User user2; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public User getUser1() { return user1; } public void setUser1(User user1) { this.user1 = user1; } public User getUser2() { return user2; } public void setUser2(User user2) { this.user2 = user2; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String add() throws Exception { System.out.println("add方法..."); return "bookEdit"; } public String del() throws Exception { System.out.println("del方法..."); return "bookEdit"; } public String edit() throws Exception { System.out.println("edit方法..."); return "bookEdit"; } public String list() throws Exception { System.out.println("list方法..."); System.out.println(user1); System.out.println(user2); System.out.println(sex); HttpServletRequest request = ServletActionContext.getRequest(); request.setAttribute("age", 12); req.setAttribute("hobby", "ccc"); return "bookEdit"; } public User getModel() { return user1; } @Override public void setServletResponse(HttpServletResponse arg0) { this.resp = arg0; } @Override public void setServletRequest(HttpServletRequest arg0) { this.req = arg0; } }
demo1界面
set方法传参
当我运行 Demo1界面,为什么user中的uname属性有值,而Demo1Action中的uanme属性没有值,这里涉及到了Struts的优先级
二、Struts的优先级Struts的优先级与我们今天的题目有非常大的联系,struts中的jar包是依赖ognl,有着依赖关系,所以讲Struts的优先级时可以围绕着ognl的两大特点来进行分享。从而解决昨天遗留的问题
导入帮助类
在demo1中我将小明设为根对象。其他的为非根对象,会进行一系列的替换值
package com.hpw.test; import ognl.OgnlContext; import ognl.OgnlException; public class Demo1 { public static void main(String[] args) { Employee e = new Employee(); e.setName("小李"); Manager m = new Manager(); m.setName("张经理"); // 创建OGNL下文,而OGNL上下文实际上就是一个Map对象 OgnlContext ctx = new OgnlContext(); // 将员工和经理放到OGNL上下文当中去 ctx.put("employee", e); ctx.put("manager", m); ctx.setRoot(e);// 设置OGNL上下文的根对象 // 表达式name将执行e.getName(),因为e对象是根对象(请注意根对象和非根对象表达式的区别) String employeeName = (String) Onglexpression.getValue("name", ctx, e); System.out.println(employeeName); // 表达式#manager.name将执行m.getName(),注意:如果访问的不是根对象那么必须在前面加上一个名称空间,例如:#manager.name String managerName = (String) Onglexpression.getValue("#manager.name", ctx, e); System.out.println(managerName); // 当然根对象也可以使用#employee.name表达式进行访问 employeeName = (String) Onglexpression.getValue("#employee.name", ctx, e); System.out.println(employeeName); Onglexpression.setValue("name", ctx, e, "小明"); employeeName = (String) Onglexpression.getValue("name", ctx, e); System.out.println(employeeName); Onglexpression.setValue("#manager.name", ctx, e, "孙经理"); managerName = (String) Onglexpression.getValue("#manager.name", ctx, e); System.out.println(managerName); Onglexpression.setValue("#employee.name", ctx, e, "小芳"); employeeName = (String) Onglexpression.getValue("name", ctx, e); System.out.println(employeeName); } }
从结果可以看出,无论怎么替换值,根对象有且只有一个(和一个良好的xml文件的起其中一个特点是相同的)
三、Ognl的特点 1、值栈是先进后出的特点
用一个案例解释
demo1
public String ognl1() { // 栈:表示一个先进后出的数据结构 ValueStack vs = ActionContext.getContext().getValueStack(); // push方法把项压入栈顶 vs.push(new Employee("zs", 22)); vs.push(new Employee("ls", 22)); vs.push(new Employee("ww", 22)); // pop方法移除栈顶对象并作为此函数的值返回该对象 Employee e = (Employee) vs.pop(); System.out.println(e.getName()); e = (Employee) vs.pop(); System.out.println(e.getName()); e = (Employee) vs.pop(); System.out.println(e.getName()); return "bookEdit"; }
struts-sy.xml
运行结果如下
Ognl的这一特点与List结合中的linkedList的堆栈的特点是一样的
2、计数是从上至下的同样的与讲上一特点用一个案列来讲解,有两个人物,一个是张雇员,薪资为2000,另一个是小明同学,编号为s001,我从中找出name和salary的值就验证了这一特点
demo1
public String ognl2() { ValueStack vs = ActionContext.getContext().getValueStack(); vs.push(new Employee("张雇员", 2000));// 1 vs.push(new Student("小明同学", "s001"));// 0 System.out.println(vs.findValue("name")); System.out.println(vs.findValue("salary2")); return "bookEdit"; }
Student类
package com.hpw.test; public class Student { private String name; private String number; public Student() { super(); } public Student(String name, String number) { super(); this.name = name; this.number = number; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } @Override public String toString() { return "Student [name=" + name + ", number=" + number + "]"; } }
Employee
package com.hpw.test; public class Employee { private String name; private Address address; private Integer salary; public Employee() { super(); } public Employee(String name, Integer salary) { super(); this.name = name; this.salary = salary; } public Integer getSalary() { return salary; } public void setSalary(Integer salary) { this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Override public String toString() { return "Employee [name=" + name + ", address=" + address + ", salary=" + salary + "]"; } }
Ognl.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Insert title here ognl的特点 值栈是符合先进后出的特点
计数是从上至下的特点
运行结果如下
将两个人物装入一个容器时,小明同学在上面,张雇员在下面,计数的时候先要取出小明同学看有没有这个值,如果有就会把对应属性的值取出来,如果没有就会进行下一步,把一个人物取出来,看有没有这个值,同样的,有对应属性的值就会取出来,没有就会一直找,直到找到为止。取值的时候也体现出了ognl的特点一
四、解决上次的问题(user中的uname属性有值,而Demo1Action中的uanme属性没有值)示意图
示意图阐释: 在Demo1Action中,有一个user对象,以及uname这一个属性,而user对象是ModelDriven接口用来定义模型的,而uname这一属性是属于Demo1Action这一个类的。在最开始的时候,我创建Demo1Action这一个类时,就已经将Demo1Action这一个类装到的一个容器的底部,之后我再实现ModerDriven接口的时候,我同样将ModerDriven接口装进了刚刚那个容器里面,同理可得:映射出一个一模一样的容器,对应的属性就装到了容器里面(首先是Demo1Action对应的uname属性,其次是ModerDriven对应的user1对象),当我把uname=ognl这一属性值加入到容器中时,首先是计数是从上至下的和先进后出的特点,将ognl值加入到ModerDriven的uname属性中,Demo1Action的uname属性就没有值了,当运行ognl.jsp时,运行出的结果往往符合了Ognl的第一特点,先进后出的特点。自然而然的uname就为null。解释昨天遗留问题正好用Ognl的两大特点验证了
Ognl最重要的就是将其中的理论知识理解透彻是最重要的,记住两大特点是首要前提,之后理解是重要过程。希望能够帮助到大家,到这里就结束了,欢迎大佬指点
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)