值栈基础学习

一.值栈是什么?
简单来说,值栈是对应每一个请求对象的轻量级的内存数据中心。

二.特点
1.它统一管理数据,供Action,Result,Interceptor等其他组件使用,这样一来,数据被集中管理,大大方便了编程。

2.大多数情况下,用户无需关心其内部,只需要去获取自己需要的数据就可以了,即用户可以隐式的使用值栈。

3.但当我们需要编写自定义的Result或拦截器等复杂功能时,还是需要显示访问值栈的,所以,我们应该掌握它。

三.值栈具体能干什么?
当有请求到达的时候,Struts2会为每个请求创建一个新的值栈,这个值栈中封装了一次请求的所有需要操作的相关数据。
正是因为值栈和请求的对应关系,因而值栈能保证线程安全地为每个请求提供公共的数据存储服务。

四.值栈的具体形式(两种)

一.狭义值栈

1.什么是狭义值栈?

通常指的是实现com.opensymphony.xwork2.util.ValueStack 接口的对象
此接口源码如下:

package com.opensymphony.xwork2.util;
import java.util.Map;

public interface ValueStack
{

    public abstract Map getContext();

    public abstract void setDefaultType(Class class1);

    public abstract void setExprOverrides(Map map);

    public abstract Map getExprOverrides();

    public abstract CompoundRoot getRoot();

    public abstract void setValue(String s, Object obj);

    public abstract void setParameter(String s, Object obj);

    public abstract void setValue(String s, Object obj, boolean flag);

    public abstract String findString(String s);

    public abstract String findString(String s, boolean flag);

    public abstract Object findValue(String s);

    public abstract Object findValue(String s, boolean flag);

    public abstract Object findValue(String s, Class class1);

    public abstract Object findValue(String s, Class class1, boolean flag);

    public abstract Object peek();

    public abstract Object pop();

    public abstract void push(Object obj);

    public abstract void set(String s, Object obj);

    public abstract int size();

    public static final String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack";
    public static final String REPORT_ERRORS_ON_NO_PROP = "com.opensymphony.xwork2.util.ValueStack.ReportErrorsOnNoProp";
}

目前就是com.opensymphony.xwork2.ognl.OgnlValueStack对象,它实现了上面接口。
由于源码过长,我们可以在类似于struts2-core-2.5.22.jar的文件中查找,也可以直接在java文件中继承它,用ctrl+左键查看。

2.狭义值栈的作用?
主要用来存取动态EL(表达式语言)运算需要的值和结果,OgnlValueStack对象主要是用来支持OGNL运算的(下一篇博客学习OGNL)。

3.狭义值栈中存放着一些OGNL可以存取访问的数据,典型如下:
Action实例。
OGNL表达式的值。
OGNL表达式产生的中间变量。

具体信息可查看源码。

二.广义值栈
通常指的是ActionContext对象,每个ActionContext是一个基本容器,包含着Action运行需要的数据。
源码如下:

package com.opensymphony.xwork2;

import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.util.ValueStack;
import java.io.Serializable;
import java.util.*;
import org.apache.struts2.dispatcher.HttpParameters;

// Referenced classes of package com.opensymphony.xwork2:
//            ActionInvocation, XWorkException

public class ActionContext
    implements Serializable
{

    public ActionContext(Map context)
    {
        this.context = context;
    }

    public void setActionInvocation(ActionInvocation actionInvocation)
    {
        put("com.opensymphony.xwork2.ActionContext.actionInvocation", actionInvocation);
    }

    public ActionInvocation getActionInvocation()
    {
        return (ActionInvocation)get("com.opensymphony.xwork2.ActionContext.actionInvocation");
    }

    public void setApplication(Map application)
    {
        put("com.opensymphony.xwork2.ActionContext.application", application);
    }

    public Map getApplication()
    {
        return (Map)get("com.opensymphony.xwork2.ActionContext.application");
    }

    public static void setContext(ActionContext context)
    {
        actionContext.set(context);
    }

    public static ActionContext getContext()
    {
        return (ActionContext)actionContext.get();
    }

    public void setContextMap(Map contextMap)
    {
        getContext().context = contextMap;
    }

    public Map getContextMap()
    {
        return context;
    }

    public void setConversionErrors(Map conversionErrors)
    {
        put("com.opensymphony.xwork2.ActionContext.conversionErrors", conversionErrors);
    }

    public Map getConversionErrors()
    {
        Map errors = (Map)get("com.opensymphony.xwork2.ActionContext.conversionErrors");
        if(errors == null)
        {
            errors = new HashMap();
            setConversionErrors(errors);
        }
        return errors;
    }

    public void setLocale(Locale locale)
    {
        put("com.opensymphony.xwork2.ActionContext.locale", locale);
    }

    public Locale getLocale()
    {
        Locale locale = (Locale)get("com.opensymphony.xwork2.ActionContext.locale");
        if(locale == null)
        {
            locale = Locale.getDefault();
            setLocale(locale);
        }
        return locale;
    }

    public void setName(String name)
    {
        put("com.opensymphony.xwork2.ActionContext.name", name);
    }

    public String getName()
    {
        return (String)get("com.opensymphony.xwork2.ActionContext.name");
    }

    public void setParameters(HttpParameters parameters)
    {
        put("com.opensymphony.xwork2.ActionContext.parameters", parameters);
    }

    public HttpParameters getParameters()
    {
        return (HttpParameters)get("com.opensymphony.xwork2.ActionContext.parameters");
    }

    public void setSession(Map session)
    {
        put("com.opensymphony.xwork2.ActionContext.session", session);
    }

    public Map getSession()
    {
        return (Map)get("com.opensymphony.xwork2.ActionContext.session");
    }

    public void setValueStack(ValueStack stack)
    {
        put("com.opensymphony.xwork2.util.ValueStack.ValueStack", stack);
    }

    public ValueStack getValueStack()
    {
        return (ValueStack)get("com.opensymphony.xwork2.util.ValueStack.ValueStack");
    }

    public void setContainer(Container cont)
    {
        put("com.opensymphony.xwork2.ActionContext.container", cont);
    }

    public Container getContainer()
    {
        return (Container)get("com.opensymphony.xwork2.ActionContext.container");
    }

    public Object getInstance(Class type)
    {
        Container cont = getContainer();
        if(cont != null)
            return cont.getInstance(type);
        else
            throw new XWorkException("Cannot find an initialized container for this request.");
    }

    public Object get(String key)
    {
        return context.get(key);
    }

    public void put(String key, Object value)
    {
        context.put(key, value);
    }

    static ThreadLocal actionContext = new ThreadLocal();
    public static final String ACTION_NAME = "com.opensymphony.xwork2.ActionContext.name";
    public static final String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack";
    public static final String SESSION = "com.opensymphony.xwork2.ActionContext.session";
    public static final String APPLICATION = "com.opensymphony.xwork2.ActionContext.application";
    public static final String PARAMETERS = "com.opensymphony.xwork2.ActionContext.parameters";
    public static final String LOCALE = "com.opensymphony.xwork2.ActionContext.locale";
    public static final String TYPE_CONVERTER = "com.opensymphony.xwork2.ActionContext.typeConverter";
    public static final String ACTION_INVOCATION = "com.opensymphony.xwork2.ActionContext.actionInvocation";
    public static final String CONVERSION_ERRORS = "com.opensymphony.xwork2.ActionContext.conversionErrors";
    public static final String CONTAINER = "com.opensymphony.xwork2.ActionContext.container";
    private Map context;

}

我们从中可以看到它其实包含了ValueStack的。

五.ActionContext的基本使用

1.如何获取?
a.若不能获取到ActionInvocation的时候,可以使用ActionContext的一个静态getContext()方法获取:

ActionContext cts=ActionContext.getContext();

b.若能获取到的时候:

ActionContext cts=actionInvocation.getInvocationContext();

2.如何使用?
其典型方法如下:
get(String key) 根据key从ActionContext当前的存储空间里面获取值。
put(String key,Object value):把值存储在ActionContext存储空间里。
ValueStack getValueStack():获取OGNL栈值。
…具体多少方法大家可查看上面源码。

六.ValueStack的基本使用

1.如何获取
直接可由ActionContext对象的getValueStcak()方法获取。

2.典型方法如下:
Object findValue(String expr):根据表达式在value stack中,按照默认的访问顺序去获取表达式对应的值。
void setValue(String expr,Object value): 根据表达式按照默认的访问顺序设置值。
Object peek(): 获取value stack中的顶层对象,不修改value stack对象。
Object pop(): 弹出顶层对象。
void push(Object o): 压入对象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值