什么是OGNL
OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。
OGNL与EL表达式对比
-
OGNL对象图导航语言,比EL表达式强大很多倍的语言
-
EL表达式只能从域中获取数据
-
OGNL可以调用对象的方法,获取struts的值栈的数据。
-
OGNL是第三方的表达式语言,用它来获取struts中值栈的数据
OGNL功能
-
支持运算符(如+-*/)
-
支持对象方法调用,如xxx.doSomeSpecial();
-
支持类静态的方法调用和值访问
-
支持赋值操作和表达式串联
-
访问OGNL上下文
-
操作集合对象
-
可以直接new一个对象
OGNL使用要素
-
表达式
-
根对象
-
Context对象(非根对象)
OGNL入门
OGNL核心OgnlContext,本质就是一个map
java程序使用ognl
@Test
public void test(){
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot("aaa");
Object obj = Ognl.getRoot(ognlContext);
System.out.println(obj);
}
获取root中的数据
可以向root当中存放Java对象
@Test
public void test2() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
User user = new User();
user.setUsername("Ryan");
user.setAge(12);
ognlContext.setRoot(user);
Object root = ognlContext.getRoot();
Object username = Ognl.getValue("username", ognlContext, root);
System.out.println(username);
}
根元素只取栈顶,可取字段
获取context中的数据
非根对象不能取字段,取数据时需要加#
@Test
public void test3() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
User user = new User();
user.setUsername("Ryan");
user.setAge(12);
ognlContext.put("UserRyan",user);
Object root = ognlContext.getRoot();
User obj = (User)Ognl.getValue("#UserRyan", ognlContext, root);
System.out.println(obj.getUsername());
System.out.println(obj.getAge());
}
获取对象方法
Object value = Ognl.getValue("'Ryan'.length()", ognlContext, root);
System.out.println(value);
获取对象静态方法
Object value1 = Ognl.getValue("@java.lang.Math@random()", ognlContext, root);
System.out.println(value1);
在 jsp 中默认不允许访问静态方法,需设置常量 struts.ognl.allowStaticEmthodAccess
开启
Jsp 中使用 Ognl
什么是值栈
-
ValueStack实际上就是一个容器。是一个接口,实现类为OgnlValueStack
-
当用户每次访问action对象的业务方法时, 会先创建ActionContext对象,包含OgnlValueStack对象,包含Action对象
-
它由Struts框架创建,当前端页面如jsp发送一个请求时,Struts的默认拦截器会将请求中的数据进行封装,并入ValueStack的栈顶
-
Struts框架中的数据就都保存到了ValueStack中,不存到域当中了。存到域当中只能在页面中把它取出来,存到值栈当中可以在任何地方取出数据,比如在页面中取出,在action中取出,在配置文件当中取出
-
ValueStack贯穿整个action的生命周期
-
action一旦创建,就会创建一个valuestack对象
-
当请求过来的时候,执行StrutsPrepareAndExecuteFilter过滤器当中的doFilter方法。在这个方法当中创建ActionContext。在创建ActionContext过程中,创建ValueStack对象。将valueStack对象传递给ActionContext对象。通过ActionContext获取值栈对象。ActionContext对象之所以以够访问servlet的API(域对象的数据)
值栈内部结构分析
-
获取值栈
ValueStack valueStack = ActionContext.getContext().getValueStack();
-
根区:存放当前 Action 相关数据
-
非根区:整个程序相关数据 req session application
值栈存放数据
// valueStack.getRoot().push(new Object());
// valueStack.getRoot().pop();
valueStack.push(new Object());
valueStack.pop();
// to req
ActionContext.getContext().put("reqName","reqValue");
// to session
ActionContext.getContext().getSession().put("sessionName","sessionValue");
//to application
值栈调试
struts 常量
JSP
<%@ taglib uri="/struts-tags" prefix="s"%>