struts2(三)——Ognl 与值栈

什么是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

<s:property value=""/>

什么是值栈

  • 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 常量

<constant name="struts.devMode" value="true" />

JSP

<%@ taglib uri="/struts-tags" prefix="s"%>
<s:debug />

原文地址:https://www.cnblogs.com/mdz3201/p/12637511.html