struts2 ValueStack(值栈)解析

Struts2一个重要点就是值栈。

ValueStack,是用来存储一些在各个action,或者说是通过s标签、el表达式等给前台Jsp等页面展示的东西。

  ValueStack是一个接口,其内部接口非常简单:

  1 /*
  2  * Copyright 2002-2007,2009 The Apache Software Foundation.
  3  *
  4  * Licensed under the Apache License, Version 2.0 (the "License");
  5  * you may not use this file except in compliance with the License.
  6  * You may obtain a copy of the License at
  7  *
  8  *      http://www.apache.org/licenses/LICENSE-2.0
  9  *
 10  * Unless required by applicable law or agreed to in writing, software
 11  * distributed under the License is distributed on an "AS IS" BASIS,
 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  * See the License for the specific language governing permissions and
 14  * limitations under the License.
 15  */
 16 package com.opensymphony.xwork2.util;
 17
 18 import java.util.Map;
 19
 20 /**
 21  * ValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated against it. When
 22  * evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the
 23  * earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending
 24  * on the expression being evaluated).
 25  */
 26 public interface ValueStack {
 27
 28     public static final String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack";
 29
 30     public static final String REPORT_ERRORS_ON_NO_PROP = "com.opensymphony.xwork2.util.ValueStack.ReportErrorsOnNoProp";
 31
 32     /**
 33      * Gets the context for this value stack. The context holds all the information in the value stack and it‘s surroundings.
 34      *
 35      * @return  the context.
 36      */
 37     public abstract Map<String, Object> getContext();
 38
 39     /**
 40      * Sets the default type to convert to if no type is provided when getting a value.
 41      *
 42      * @param defaultType the new default type
 43      */
 44     public abstract void setDefaultType(Class defaultType);
 45
 46     /**
 47      * Set a override map containing <code>key -> values</code> that takes precedent when doing find operations on the ValueStack.
 48      * <p/>
 49      * See the unit test for ValueStackTest for examples.
 50      *
 51      * @param overrides  overrides map.
 52      */
 53     public abstract void setExprOverrides(Map<Object, Object> overrides);
 54
 55     /**
 56      * Gets the override map if anyone exists.
 57      *
 58      * @return the override map, <tt>null</tt> if not set.
 59      */
 60     public abstract Map<Object, Object> getExprOverrides();
 61
 62     /**
 63      * Get the CompoundRoot which holds the objects pushed onto the stack
 64      *
 65      * @return the root
 66      */
 67     public abstract CompoundRoot getRoot();
 68
 69     /**
 70      * Attempts to set a property on a bean in the stack with the given expression using the default search order.
 71      *
 72      * @param expr  the expression defining the path to the property to be set.
 73      * @param value the value to be set into the named property
 74      */
 75     public abstract void setValue(String expr, Object value);
 76
 77     /**
 78      * Attempts to set a property on a bean in the stack with the given expression using the default search order.
 79      * N.B.: unlike #setValue(String,Object) it doesn‘t allow eval expression.
 80      * @param expr  the expression defining the path to the property to be set.
 81      * @param value the value to be set into the named property
 82      */
 83     void setParameter(String expr, Object value);
 84
 85     /**
 86      * Attempts to set a property on a bean in the stack with the given expression using the default search order.
 87      *
 88      * @param expr                    the expression defining the path to the property to be set.
 89      * @param value                   the value to be set into the named property
 90      * @param throwExceptionOnFailure a flag to tell whether an exception should be thrown if there is no property with
 91      *                                the given name.
 92      */
 93     public abstract void setValue(String expr, Object value, boolean throwExceptionOnFailure);
 94
 95     public abstract String findString(String expr);
 96     public abstract String findString(String expr, boolean throwExceptionOnFailure);
 97
 98     /**
 99      * Find a value by evaluating the given expression against the stack in the default search order.
100      *
101      * @param expr the expression giving the path of properties to navigate to find the property value to return
102      * @return the result of evaluating the expression
103      */
104     public abstract Object findValue(String expr);
105
106     public abstract Object findValue(String expr, boolean throwExceptionOnFailure);
107
108     /**
109      * Find a value by evaluating the given expression against the stack in the default search order.
110      *
111      * @param expr   the expression giving the path of properties to navigate to find the property value to return
112      * @param asType the type to convert the return value to
113      * @return the result of evaluating the expression
114      */
115     public abstract Object findValue(String expr, Class asType);
116     public abstract Object findValue(String expr, Class asType,  boolean throwExceptionOnFailure);
117
118     /**
119      * Get the object on the top of the stack <b>without</b> changing the stack.
120      *
121      * @return the object on the top.
122      * @see CompoundRoot#peek()
123      */
124     public abstract Object peek();
125
126     /**
127      * Get the object on the top of the stack and <b>remove</b> it from the stack.
128      *
129      * @return the object on the top of the stack
130      * @see CompoundRoot#pop()
131      */
132     public abstract Object pop();
133
134     /**
135      * Put this object onto the top of the stack
136      *
137      * @param o the object to be pushed onto the stack
138      * @see CompoundRoot#push(Object)
139      */
140     public abstract void push(Object o);
141
142     /**
143      * Sets an object on the stack with the given key
144      * so it is retrievable by {@link #findValue(String)}, {@link #findValue(String, Class)}
145      *
146      * @param key  the key
147      * @param o    the object
148      */
149     public abstract void set(String key, Object o);
150
151     /**
152      * Get the number of objects in the stack
153      *
154      * @return the number of objects in the stack
155      */
156     public abstract int size();
157
158 }

和一个普通的栈没多大区别。

他的实现类就比较复杂了(其实也不复杂...)

public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack {

这里贴一部分。

现在来说说值栈的具体作用:

当用户发出一个请求,对应一个action,这个时候你要用相应的Action类实例化相应的action去处理,这个时候,如果你在这个Action中,加上一个ActionContext(或者其他的几个接口),如下:

ActionContext.getContext().put("list", leaveWordsList);

这个时候,这个list就会被放入值栈(为什么list会放入值栈将在后面写出)。

然后,你就能在另一个Action,或者是jsp页面(通过el表达式等)得到值栈中的属性。

private LeaveWordDao leaveWordDao;

    private LeaveWord leaveWord;

    private LeaveWord resultLeaveWord;

    public void setResultLeaveWord(LeaveWord resultLeaveWord) {
        this.resultLeaveWord = resultLeaveWord;
    }

    @Override
    public void setSession(Map<String, Object> arg0) {
        sessionMap = arg0;
    }

    @Override
    public void setApplicationContext(ApplicationContext arg0) throws BeansException {
        this.applicationContext = arg0;
    }

通过你在另一个Action中的属性以及setXX方法去得到,当然,这只是会得到栈顶开始出栈的第一个匹配的同名属性,如果你要得到第二个,第三个,还有别的方法。

当然,你也可以在jsp页面中得到,也就是ognl,如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <s:iterator value="list" status="li">
        <s:property value="name"/>
        <s:property value="title"/>
        <s:property value="content"/>
        <s:property value="lastDate"/>
        <form action="reply.action">
        <input type="hidden" name="leaveWord_id" value="${id}">
            <input type="submit" value="回复">
        </form>
        </br>
    </s:iterator>
</body>
</html>

接下来,说说为什么ActionContext起到这样的作用:

1    /**
2      * Sets the OGNL value stack.
3      *
4      * @param stack the OGNL value stack.
5      */
6     public void setValueStack(ValueStack stack) {
7         put(VALUE_STACK, stack);
8     }

这是ActionContext中的一部分,可以看到,它持有了ValueStack实例,既然持有实例,那么将属性存储进去就很容易了吧。

另外,值栈的生命周期 = Request的生命周期

博文为原创,如需转载,请标注原处,谢谢。

时间: 2024-10-06 20:26:00

struts2 ValueStack(值栈)解析的相关文章

ValueStack值栈和ActionContext

Struts2在OGNL之上提供的最大附加特性就是支持值栈(ValueStack),在OGNL上下文中只能有一个根对象,Struts2的值栈则允许存在许多虚拟对象. 一:值栈(ValueStack) 我们可以先获得ValueStack接口对象 // 01.获取到ValueStack接口对象 ,在request请求中. HttpServletRequest request = ServletActionContext.getRequest(); ValueStack vs = (ValueStac

Struts 中 ActionContext ctx.put()把数据放到ValueStack里之数据传输背后机制:ValueStack(值栈)

1.     数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! ValueStack基础:OGNL要了解ValueStack,必须先理解OGNL(Object Graphic Navigatino Language)! OGNL是Struts2中使用的一种表达式语言,它可以用于JSP的标签库中,以便能够方便的访问各种对象的属性:它用于界面将参数传递到Action(并进行类型转换)中:它还可以用于struts2的配置文件中!所以,非常有必要理

[ SSH框架 ] Struts2框架学习之三(OGNl和ValueStack值栈学习)

一.OGNL概述 1.1 什么是OGNL OGNL的全称是对象图导航语言( object-graph Navigation Language),它是一种功能强大的开源表达式语言,使用这种表达式语言,可以通过某种表达式语法,存取Java对象的任意属性,调用Java对象的方法,同时能够自动实现必要的类型转换.如果把表达式看作是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁. 1.2 OGNL的作用 Struts2默认的表达式语言就是OGNL,它具有以下特点:

Struts2的值栈和对象栈

ValueStack 如何得到值栈: 如何将对象存入值栈: 让值栈执行表达式来获得值: 在JSP中跳过栈顶元素直接访问第二层: 在JSP中访问值栈对象本身(而不是它们的属性) ActionContext ValueStack与ActionContext的联系和区别: 如何获得ActionContext: 如何向ActionContext中存入值: 如何从ActionContext中读取值: HttpServletRequest类或request的Map 使用HttpServletRequest类

【struts2】值栈(后篇)

在值栈(前篇)我们学习了值栈的基本知识,接下来,来看看在程序中具体如何使用值栈. 1 ActionContext的基本使用 1.1 如何获取? 要获取ActionContext有两个基本的方法,如果在不能获取到ActionInvocation的地方,可以直接使用ActionContext一个静态的getContext方法,就可以访问到当前的ActionContext了,示例如下: ActionContext ctx = ActionContext.getContext(); 如果在能获取到Act

【struts2】值栈(前篇)

1 值栈是什么? 简单的说:值栈是对应每一个请求对象的轻量级的内存数据中心. Struts2中一个很激动人心的特性就是引入了值栈,在这里统一管理着数据,供Action.Result.Interceptor等Struts2的其他部分使用,这样一来,数据被集中管理起来而不会凌乱,大大方便了程序编写.Struts2中关于值栈的另外一个很激动人心的特性就是:大多数情况下,你根本无需关心值栈,你不用管它在哪里,不用管它里面有什么,你只需要去获取自己需要的数据就可以了.也就是说,你可以隐式的使用值栈.当然,

Struts2 之值栈

值栈(ValueStack) http://www.cnblogs.com/bgzyy/p/8639893.html 这是我的有关 struts2 的第一篇文章,对于里面我们说到的一个 struts2 HelloWorld 小练习,即在输入框输入信息提交后在另外一个页面显示输入的信息,显示页面的代码如下: UserName: ${userName}<br> Email: ${email}<br> Address: ${address}<br> 为什么这样一个简单的标签就

关于Struts2的值栈和OGNL的简单理解

1.值栈是什么? 值栈是对应每一个请求对象的内存数据中心.每次请求一个action生成一个狭义上的值栈(ValueStack).这个值栈存储了我们定义在action中的每个属性的值,这些属性必须有get和set方法,以致于我们可以在jsp页面中使用EL表达式. 2.值栈的作用: 值栈能够在线程安全的情况下提供公共的数据存取服务.当有请求到达时,struts会为每个请求创建一个新的值栈.值栈封装了一次请求所有需要操作的相关的数据. 3.值栈的内容: 在struts中是有广义和狭义值栈之分的.狭义值

Struts2 的 值栈

1.ValueStack 对象的内部有2个逻辑部分: -- ObjectStack:Struts 把 Action 和相关对象亚茹ObjectStack中 -- ContextMap:Sturts 把各种各样的映射关系(一些 Map 类型的对象)压入ContextMap中,实际上就是对ActionContext的一个引用 2.Struts 会把下面这些映射压入ContextMap中: -- parameters: 该Map中包含当前请求的请求参数: -- request: 该Map中包含当前re

Struts2的值栈

一次对于action的request只有一个值栈,对于普通jsp页面的请求值栈为空. 对于result,在服务器端forward时(dispatcher,chain)时不需要使用参数从之前的值栈中拿出参数t再通过"?tparam=${t}"传递来实现动态结果集. 在客户端forward(redirect,redirectAction)时需要用以上方法传递参数,然后再在新的普通jsp页面或者action中同过"#paramenters.t"获得该参数.