Struts2值栈学习

具体:http://www.verydemo.com/demo_c140_i33133.html

1:简单的说,值栈是对应每一个请求对象的轻量级的数据存储中心,在这里统一管理着数据,供Action、Result、Interceptor等Struts2的其他部分使用,这样数据被集中管理起来而不凌乱。

      简单的说,值栈能够线程安全的为每个请求提供公共的数据存取服务。

      当有请求的时候,Struts2会为每个请求创建一个新的值栈,也就是说,栈和请求是一一对应的,不同的请求,值栈也不一样,而值栈封装了一次请求所有需要操作的相关的数据。

     正是因为值栈和请求的对应关系,因此值栈能保证线程安全的为每个请求提供公共的数据存取服务。

2:狭义值栈

     通常是指com.opensymphony.xwork2.util.ValueStack接口的对象,目前就是com.opensymphony.xwork2.ognl.OgnlValueStack对象。

     狭义值栈主要用来存放动态EL(表达式语言)运算需要的值和结果,当然OgnlValueStack对象主要是用来支持OGNL(对象图导航语言)运算的。

     狭义值栈中存放着一些OGNL可以访问的数据,如下:

        a:action的实例,这样就可以通过OGNL来访问Action实例中的属性的值了。

        b:OGNL表达式运算的值,可以设置到值栈中,可以主动访问值栈对象,强行设置。

        c:OGNL表达式产生的中间变量,比如使用Struts2标签的时候,使用循环标签,自然会有循环的变量,这些都放在值栈中。

3:广义值栈

   通常是ActionContext对象,ActionContext是Action运行的上下文,每个ActionContext是一个基本的容器,包含着Aciton运行需要的数据,比如请求参数,会话等。

  ActionContext也是线程安全的,每个线程都有一个独立的ActionContext,这样就不用担心值栈中值得线程安全问题了。

  ActionContext里面存储着很多值,如下:

....................................................................

     b:Request的Attribute,请求中的属性,这里是一个Map,存放着请求对象的属性数据,这些数据和请求对象的Attribute是联动的。

     c:Application的Attribute,应用的属性,这里是一个Map,存放着应用对象的属性数据,这些数据和应用对象的attribute是联动的。

     d:ValueStack,也就是狭义值栈,ActionContext是以value stack作为被OGNL访问的根,简单的说,OGNL在没有特别指明的情况下,访问的就是value stack的值。

     e:attr,在所有的属性范围中获取值,依次搜索page, request, session 和applicaion

4:ActionContext的使用

   获取,通过两种方式,第一种,使用ActionContext自身的方法来获取

     ActionContext ctx = ActionContext.getContext();

   第二种,使用ActionInvocation来获取

     ActionContext ctx = actionInvocation.getInvocationContext();

   它的典型方法如下:

    Objectget(String key):Returns a value that is stored in the current ActionContext by doing a lookup using the value's key.

  <code>void put(String key,Object value):Stores a value in the current ActionContext.

<code>  <code>Map<String,Object>getApplication():  Returns a Map of the ServletContext when in a servlet environment or a generic application level Map otherwise.

<code><code>                                         即返回ServletContext中返回的值

<code><code><code>  Map<String,Object>getSession():Gets the Map of HttpSession values when in a servlet environment or a generic session map otherwise.

<code>  <code>Map<String,Object>getContextMap():Gets the context map.

<code><code><code><code>  <code>Map<String,Object>getParameters(): Returns a Map of the HttpServletRequest parameters when in a servlet environment or a generic Map of parameters otherwise.

<code><code><code><code><code>  

<code><code><code><code>5:ValueStack的使用

<code><code><code><code>   ValueStack有一个特点,如果访问的值栈里有多个对象,且相同的属性在多个对象中同时出现,则值栈会按照从栈顶到栈底的顺序,寻找第一个匹配的对象。

<code><code><code><code><br />

<code><code><code><code>      图:用户输入了aa的username

<code><code><code><code><br />

<code><code><code><code><br />

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.PreResultListener;

public class MyPreResultListener implements PreResultListener {

	@Override
	public void beforeResult(ActionInvocation invocation, String resultCode) {
		System.out.println("现在处理Result执行前的功能, result=" + resultCode);
		
		//在Result处理之前修改value stack里面的username对应的值
	    invocation.getInvocationContext().getValueStack().setValue("username", "被修改了");

	}

}

import com.capinfotech.listener.MyPreResultListener;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class PreResultAction extends ActionSupport {

	private String username;
	private String password;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
	public String execute() {
		System.out.println("用户输入的参数为,username:" + username + ", password:" + password);
		
		ActionContext context = ActionContext.getContext();
		MyPreResultListener preListener = new MyPreResultListener();
		context.getActionInvocation().addPreResultListener(preListener);
		
		return "success";
		
	}

}