OGNL介绍:
一:OGNL的全称是Object Graph Navigation Language(对象图导航语言),
它是一种强大的表达式语言
二:OgnlContext(ongl上下文)OgnlContext=根对象(1)+非根对象(N)
根对象只有一个,非根对象可以有无数个
用例题来理解ongl:
例题一:
package com.sg.one.test; import ognl.OgnlContext; import ognl.OgnlException; public class Demo1 { /** * @param args * @throws OgnlException */ 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); } }
分析:
这是新建了两个实体类(Employee,Manager)并且为其的Name属性赋值
这一步首先是创建一个上下文ctx,然后将上一步新建的Employee,Manager放入到ctx上下文中,最后将Employee设置为根对象
做例题:
一:
这一题的输出结果是小李
分析:employeeName的取值操作取的是根对象,表达式name执行e.getName()所以结果为小李
二:
这一题的输出结果为张经理
分析:因为manager.name执行的是m.getName(),所以输出结果为张经理
三:
这一题的输出结果为小李
分析:原理和第二题一样是调用了e.getName()
四:
这一题的输出结果为小明
分析: 第一行代码是给小明赋值给name,这里的name是根对象的name,所以把上面的小李替换成了小明
五:
这一题的输出结果为孙经理
分析:和上一题原理差不多,但是manager.name所以是赋值给manager把上面的张经理替换成了孙经理
六:
这一题输出结果为小芳
分析:这一题是将小芳赋值给employee,所以输出为小芳
所有结果展示:
值栈的使用:
一:验证先进后出
package com.sg.one.test; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.util.ValueStack; public class Demo7 { /** * * 值栈的使用 * */ public String main1() { // 栈:表示一个先进后出的数据结构 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"; } /** * 此例用于模拟struts2的值栈计算过程 * * @param args */ public String main2() { 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")); ActionContext ac = ActionContext.getContext(); return "bookEdit"; } }
分析:
首先新建一个栈,然后一次新建对象
输出的结果依次为(ww,ls,zs)
分析:因为栈是先进后出,ww最后一个进来那么自然是第一个出去
结果展示:
二:验证取值是从上至下的
两个实体类(Employee,Student)
Employee
package com.sg.one.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 + "]"; } }
Student
package com.sg.one.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 + "]"; } }
第一个输出为小明同学
第二个输出为2000
分析:第一个输出的为小明同学,因为是先进后出的原理
这个时候看student的实体类里面是没有salary属性的,但这里还是能取到值是因为值栈的第二个特点从上至下取值,只要里面有这个那么就会取到
输出结果展示: