Struts的ValueStack

Struts2是通过ValueStack来进行赋值与取值的。
ValueStack实际上就是对OGNL的封装,OGNL主要的功能就是赋值与取值。

ValueStack中的数据,分两个部分存放:root和context

同时ValueStack暴露相关的接口(赋值和取值):
void setValue(String expr, Object value);
Object findValue(String expr);
通过OGNL表达式对ValueStack中的数据进行操作。

1) root
ValueStack中的root对象是CompoundRoot。
CompoundRoot继承了ArraryList,提供了额外的方法:push()和pop()方法,用来对root对象中所包含的数据进行存取。
正是通过这两个方法,CompoundRoot变成了一个栈结构。
压栈操作,将导致对象被放到CompoundRoot的第0个元素上(第0个元素是栈顶),其它对象被依次往后移动;
出栈操作,将导致CompoundRoot的第0个元素被移除(即栈顶元素被弹出),其它对象被依次往前移动

OGNL只能访问被压入堆栈(CompoundRoot)中的元素。

在Struts2中,一个请求在最终到达Action的方法之前,Action对象本身会被压入
ValueStack的CompoundRoot对象中。
所以Action对象是CompoundRoot对象中的一个元素,可以使用OGNL表达式直接访问。

在jSP页面中,使用标签,将CompoundRoot栈中的值取出。
标签中的OGNL表达式,最终会交给ValueStack来解释。
比如:"username"就是一个OGNL表达式,意思是调用root对象的getUsername()方法。

  1. Context

由于在OGNL中,不支持多个root对象,但在struts2的OGNL的表达式中,
有可能需要访问到多个毫不相干的对象。这时候,我们把表达式中需要用到的对象放到Map中,
传递给OGNL,进行访问。这个Map对象,称为context。

可见valueStack对OGNL进行了扩展,使OGNL表达式可以访问到多个root对象。

要在表达式中访问到context中的对象,需要使用“#对象名称”的语法规则。

表示将context对象的元素放入到CompoundRoot对象的栈顶。访问完后,

context对象的元素会从栈顶移出,自动释放。

当CompoundRoot栈中存在多个不相干的root对象时,使用 #root[n]. 进行访问,
n是root对象当前在栈中的顺序。从0开始。

public class UserAction {  
  
    private String username;  
  
    //查看用户的详细信息  
    public String detail(){  
  
       username = "张三";        
  
       List list = new ArrayList();  
       for(int i=0; i<10; i++){  
           User user = new User();  
           user.setUsername("User"+i);  
           list.add(user);  
       }  
  
       ActionContext.getContext().put("users", list);        
  
       User u = new User();  
       u.setUsername("赵毅");  
       ActionContext.getContext().getValueStack().push(u);        
  
       return "detail";  
    }  

对应的JSP如下:

  

你可能感兴趣的:(Struts的ValueStack)