Struts2中的ValueStack

来源:互联网 发布:淘宝售后用语 编辑:程序博客网 时间:2024/04/29 03:36

Struts2中的ValueStack

一、值栈

 

值栈(ValueStack)是Struts 2 的一个核心概念,类似于正常的栈,符合后进先出的栈特点,可以在值栈中放入、删除和查询对象。Struts 2对OGNL进行了扩充,将值栈作为OGNL的根对象。 ValueStack实际上就是对OGNL的封装,OGNL主要的功能就是赋值与取值,Struts2正是通过ValueStack来进行赋值与取值的!

 


ValueStack是一个接口,而OgnlValueStack是strtus2中的缺省实现。ValueStack中的数据,分两个部分存放:root和context(这与OGNL中的概念一致),同时ValueStack暴露相关的接口:

void setValue(String expr, Object value);

Object findValue(String expr);

用来通过OGNL表达式对ValueStack中的数据进行操作!


二、栈的基本操作

 

ValueStack中的root对象是CompoundRoot,CompoundRoot继承了ArraryList,提供了额外的方法:push()和pop()方法,用来对root对象中所包含的数据进行存取!

public class CompoundRoot extends ArrayList {

 

    public CompoundRoot() {

    }

 

    public CompoundRoot(List list) {

        super(list);

    }

 

 

    public CompoundRoot cutStack(int index) {

        return new CompoundRoot(subList(index, size()));

    }

 

    public Object peek() {

        return get(0);

    }

 

    public Object pop() {

        return remove(0);

    }

 

    public void push(Object o) {

        add(0, o);

    }

}
 

 

正是通过这两个方法,CompoundRoot变成了一个栈结构!压栈操作,将导致对象被放到CompoundRoot的第0个元素上(第0个元素是栈顶),其它对象被依次往后移动;出栈操作,将导致CompoundRoot的第0个元素被移除(即栈顶元素被弹出),其它对象被依次往前移动!

 

OGNL不支持多个root对象,而struts2能够支持多个root对象,它对OGNL做了扩展。

如果某个OGNL表达式被传递给ValueStack(即调用ValueStack的setValue或findValue方法),而表达式中包含有对root对象的访问操作,ValueStack将依次从栈顶往栈底搜索CompoundRoot对象中所包含的对象,看哪个对象具有相应的属性,找到之后,立刻返回。

 

在Struts2中,一个请求在最终到达Action的方法之前,Action对象本身会被压入ValueStack(实际上就是放到ValueStack的CompoundRoot中),所以Action对象是CompoundRoot中的一个元素。看下面的代码:

public class UserAction {

    private String username;

    private Integer age;

    private boolean valid;

   

    //查看用户的详细信息

    public String detail(){

      

       username = "张三";

       age = 18;

       valid = true;

      

       return "detail";

    }
 

在Action中,给Action的username/age/valid赋值。Detail页面如下:

username:<s:property value="username"/> <br/>

valid:<s:property value="valid"/> <br/>

age:<s:property value="age"/> <br/>
 

上述JSP页面将能正确将它们的值取出。<s:property value=”ognl表达式”/>。在s:property标签中的OGNL表达式,最终会交给ValueStack来解释。username就是一个OGNL表达式,意思是调用root对象的getUsername()方法。Struts2将自动搜索CompoundRoot中有哪些元素(从第0个元素开始搜索),检测这些元素是否有getUsername()方法,如果第0个元素没有getUsername()方法,将继续搜索第1、2、3……个元素是否有getUsername()方法。

 

在上面的例子中,CompoundRoot中只有一个对象,就是userAction对象,而这个对象中正好有getUsername()方法,所以,上述JSP代码将能够将值正确取出。

再看下面的例子:

public class UserAction {

    private String username;

    private String name;

   

    //查看用户的详细信息

    public String detail(){

       username = "张三";

       name = "王五";

      

       User u = new User();

       u.setUsername("赵毅");

       ActionContext.getContext().getValueStack().push(u);

      

       return "detail";

    }
 

在上面这个UserAction的代码中,我们直接调用ActionContext.getContext().getValueStack().push()方法,把一个User对象(这个对象拥有getUsername()和setUsername()方法)直接压入到ValueStack中,这时候,在ValueStack的CompoundRoot中将有两个元素:第0个元素是刚刚压入的user对象[赵毅],而第1个元素是userAction对象[张三],如果在JSP中使用下面的表达式来取值:

<s:property value=”username”/> ,那么输出的值将是“赵毅”!道理上面已经讲过了,struts2将会从第0个元素开始搜索CompoundRoot中的对象,第0个元素正是刚刚压入的那个user对象!

如果在JSP中使用<s:property value=”name”/>来取值,将取出“王五”,因为第0个元素user对象没有name属性,所以,会继续搜索第1个元素userAction对象,在这个对象中就有name属性了!

 

三、值栈中的Action对象

Struts 2总是把Action实例放置在栈顶。因为Action在值栈中,而值栈又是OGNL的根,所有引用Action的属性可以省略 “#”标记,这就是可以在结果页面中直接访问Action的原因

   <s:property value="username"/>

如果访问ActionContext中的其他对象,则必须使用“#”标记,以便让OGNL知道不要在根对象中查找,而是查看其他非根对象


四、ValueStack API
   com.opensymphony.xwork2.util
Interface ValueStack
All Known Implementing Classes:
OgnlValueStack

--------------------------------------------------------------------------------

public interface ValueStackValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated against it. When evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending on the expression being evaluated).

 


--------------------------------------------------------------------------------

Field Summary
static String REPORT_ERRORS_ON_NO_PROP
           
static String VALUE_STACK
           
  Method Summary
 String findString(String expr)
           
 Object findValue(String expr)
          Find a value by evaluating the given expression against the stack in the default search order.
 Object findValue(String expr, Class asType)
          Find a value by evaluating the given expression against the stack in the default search order.
 Map getContext()
          Gets the context for this value stack.
 Map getExprOverrides()
          Gets the override map if anyone exists.
 CompoundRoot getRoot()
          Get the CompoundRoot which holds the objects pushed onto the stack
 Object peek()
          Get the object on the top of the stack without changing the stack.
 Object pop()
          Get the object on the top of the stack and remove it from the stack.
 void push(Object o)
          Put this object onto the top of the stack
 void set(String key, Object o)
          Sets an object on the stack with the given key so it is retrievable by findValue(String), findValue(String, Class)
 void setDefaultType(Class defaultType)
          Sets the default type to convert to if no type is provided when getting a value.
 void setExprOverrides(Map overrides)
          Set a override map containing key -> values that takes precedent when doing find operations on the ValueStack.
 void setValue(String expr, Object value)
          Attempts to set a property on a bean in the stack with the given expression using the default search order.
 void setValue(String expr, Object value, boolean throwExceptionOnFailure)
          Attempts to set a property on a bean in the stack with the given expression using the default search order.
 int size()
          Get the number of objects in the stack
 

Field Detail


VALUE_STACK
static final String VALUE_STACKSee Also:
Constant Field Values

--------------------------------------------------------------------------------

REPORT_ERRORS_ON_NO_PROP
static final String REPORT_ERRORS_ON_NO_PROPSee Also:
Constant Field Values
Method Detail

getContext
Map getContext()Gets the context for this value stack. The context holds all the information in the value stack and it's surroundings.

Returns:
the context.

--------------------------------------------------------------------------------

setDefaultType
void setDefaultType(Class defaultType)Sets the default type to convert to if no type is provided when getting a value.

Parameters:
defaultType - the new default type

--------------------------------------------------------------------------------

setExprOverrides
void setExprOverrides(Map overrides)Set a override map containing key -> values that takes precedent when doing find operations on the ValueStack.
See the unit test for ValueStackTest for examples.


Parameters:
overrides - overrides map.

--------------------------------------------------------------------------------

getExprOverrides
Map getExprOverrides()Gets the override map if anyone exists.

Returns:
the override map, null if not set.

--------------------------------------------------------------------------------

getRoot
CompoundRoot getRoot()Get the CompoundRoot which holds the objects pushed onto the stack

Returns:
the root

--------------------------------------------------------------------------------

setValue
void setValue(String expr,
              Object value)Attempts to set a property on a bean in the stack with the given expression using the default search order.

Parameters:
expr - the expression defining the path to the property to be set.
value - the value to be set into the named property

--------------------------------------------------------------------------------

setValue
void setValue(String expr,
              Object value,
              boolean throwExceptionOnFailure)Attempts to set a property on a bean in the stack with the given expression using the default search order.

Parameters:
expr - the expression defining the path to the property to be set.
value - the value to be set into the named property
throwExceptionOnFailure - a flag to tell whether an exception should be thrown if there is no property with the given name.

--------------------------------------------------------------------------------

findString
String findString(String expr)
--------------------------------------------------------------------------------

findValue
Object findValue(String expr)Find a value by evaluating the given expression against the stack in the default search order.

Parameters:
expr - the expression giving the path of properties to navigate to find the property value to return
Returns:
the result of evaluating the expression

--------------------------------------------------------------------------------

findValue
Object findValue(String expr,
                 Class asType)Find a value by evaluating the given expression against the stack in the default search order.

Parameters:
expr - the expression giving the path of properties to navigate to find the property value to return
asType - the type to convert the return value to
Returns:
the result of evaluating the expression

--------------------------------------------------------------------------------

peek
Object peek()Get the object on the top of the stack without changing the stack.

Returns:
the object on the top.
See Also:
CompoundRoot.peek()

--------------------------------------------------------------------------------

pop
Object pop()Get the object on the top of the stack and remove it from the stack.

Returns:
the object on the top of the stack
See Also:
CompoundRoot.pop()

--------------------------------------------------------------------------------

push
void push(Object o)Put this object onto the top of the stack

Parameters:
o - the object to be pushed onto the stack
See Also:
CompoundRoot.push(Object)

--------------------------------------------------------------------------------

set
void set(String key,
         Object o)Sets an object on the stack with the given key so it is retrievable by findValue(String), findValue(String, Class)

Parameters:
key - the key
o - the object

--------------------------------------------------------------------------------

size
int size()Get the number of objects in the stack

Returns:
the number of objects in the stack