博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ValueStack中的context与ActionContext的区别
阅读量:4326 次
发布时间:2019-06-06

本文共 6307 字,大约阅读时间需要 21 分钟。

1、值栈的简单定义:

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

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

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

      (4)就是ROOT根对象,ognl访问值栈不用加任何的访问前缀,只需action中声明相应的属性,并且生成属性对应的set和get方法,页面中通 过struts2标签就可以存放/取出值栈中的值,EL表达式${username}如果没有加访问范围,访问的也是值栈,这只是最简单的值栈应用

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

2、actionContext(action上下文)的简单定义:

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

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

       (3)获得ActionContext对象的方式:

                 第一种,使用ActionContext自身的方法来获取: ActionContext ctx = ActionContext.getContext();

                 第二种,使用ActionInvocation来获取:ActionContext ctx = actionInvocation.getInvocationContext();

       (4)ActionContext里面存储着很多值:

                  a:Request的Parameters,请求中的参数,注意这里的数据是从数据对象中复制来的,因此这里的数据的变化是不会影响到请求对象里面的参数的值的。

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

                  c:Session的Attribute,会话中的助兴,这里是一个Map,存放着会话对象的属性数据,这些数据和会话对象的attribute是联动的。            

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

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

        (5)ongl表达式取出action上下文中的值:

                   由于Struts2框架把OGNLContext设置为ActionContext,还把代表application、session、request这些对象的Map对象也放到ActionContext中去。

                  又因为ActionContext为非根对象,所以OGNL表达式访问ActionContext(action上下文)里面的application、session、request、attr对象中的值时,

                  需要加访问前缀#,以便告诉OGNL,寻值不是从根对象中,而是从action上下文的其他对象中寻找

 

|--application                     |                     |--session     context map-----|   (ActionContext)   |-value stack(root)                     |                     |--action (the current action)                     |                     |--request                     |                     |--parameters                     |                     |--attr (searches page, request, session, then application scopes) 值栈中取值:
EL表达式写法${作用域属性名}   ognl表达式%{作用域属性名}  也可以是使用Struts标签
jstl——JSP Standard Tag Library,(引入:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>) el——Expressiong Language ognl——Object Graph Notation Language。 一种是标签,一种是表达式。 jstl能用于servlet和jsp中, struts标签针对于使用了struts的项目。(引入:<%@ taglib uri="/struts-tags" prefix="s"%>) 而el表达式是应用在JSP中,简化一些代码用的。 而struts2默认的是ognl表达式,所以说ognl表达式不一定就是和struts一起用的,但是使用了struts框架可以使用ongl。 关于值栈中context(即ActionContext)的关系源码如下:
public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack {    public static final String THROW_EXCEPTION_ON_FAILURE = OgnlValueStack.class.getName() + ".throwExceptionOnFailure";    private static final long serialVersionUID = 370737852934925530L;    private static final String MAP_IDENTIFIER_KEY = "com.opensymphony.xwork2.util.OgnlValueStack.MAP_IDENTIFIER_KEY";    private static final Logger LOG = LoggerFactory.getLogger(OgnlValueStack.class);    CompoundRoot root;    transient Map
context;//成员变量 Class defaultType; Map
overrides; transient OgnlUtil ognlUtil; transient SecurityMemberAccess securityMemberAccess; private transient XWorkConverter converter; private boolean devMode; private boolean logMissingProperties; protected OgnlValueStack(XWorkConverter xworkConverter, CompoundRootAccessor accessor, TextProvider prov, boolean allowStaticAccess) { setRoot(xworkConverter, accessor, new CompoundRoot(), allowStaticAccess); push(prov); } protected OgnlValueStack(ValueStack vs, XWorkConverter xworkConverter, CompoundRootAccessor accessor, boolean allowStaticAccess) { setRoot(xworkConverter, accessor, new CompoundRoot(vs.getRoot()), allowStaticAccess); } @Inject public void setOgnlUtil(OgnlUtil ognlUtil) { this.ognlUtil = ognlUtil; securityMemberAccess.setExcludedClasses(ognlUtil.getExcludedClasses()); securityMemberAccess.setExcludedPackageNamePatterns(ognlUtil.getExcludedPackageNamePatterns()); securityMemberAccess.setExcludedPackageNames(ognlUtil.getExcludedPackageNames()); securityMemberAccess.setDisallowProxyMemberAccess(ognlUtil.isDisallowProxyMemberAccess()); } protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot,boolean allowStaticMethodAccess) { this.root = compoundRoot; this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess); //在添加根对象时,OGNL创建了Context对象,并在该对象(该对象实质是一个Map)中放置值栈对象的地址。 //因为context对象的外部引用名为可以理解为ActionCotext所以 //可以通过context(即ActionContext)获取当前的值栈对象。 this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess); context.put(VALUE_STACK, this); Ognl.setClassResolver(context, accessor); ((OgnlContext) context).setTraceEvaluations(false); ((OgnlContext) context).setKeepLastEvaluation(false); }

 

public String execute(){        ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);        Map
context = valueStack.getContext(); context.put("dome", "shanghai"); ActionContext context2 = ActionContext.getContext(); context2.put("dome", "beijing"); ValueStack valueStack2 = context2.getValueStack(); System.out.println("context="+context); System.out.println("context2="+context2); System.out.println("-------------------------------值栈--------------------------------------"); System.out.println("valueStack2="+valueStack2); System.out.println("valueStack="+valueStack); return "success"; }
dome:beijing context=ognl.OgnlContext@c9e5e2bacontext2=com.opensymphony.xwork2.ActionContext@25bf9b4b-------------------------------值栈--------------------------------------valueStack2=com.opensymphony.xwork2.ognl.OgnlValueStack@1640d7b0valueStack=com.opensymphony.xwork2.ognl.OgnlValueStack@1640d7b0
输出的结果显示:

ValueStack中的Context域与ActionContext的Context域是相关联域。

ActionContext中存储了值栈的内存地址,可以理解为ValueStack的Context与ActionContext是同一个值。

 

转载于:https://www.cnblogs.com/flytogalaxy/p/7792247.html

你可能感兴趣的文章
在webconfig中写好连接后,在程序中如何调用?
查看>>
限制用户不能删除SharePoint列表中的条目(项目)
查看>>
【Linux网络编程】使用GDB调试程序
查看>>
feign调用spring clound eureka 注册中心服务
查看>>
ZT:Linux上安装JDK,最准确
查看>>
LimeJS指南3
查看>>
关于C++ const成员的一些细节
查看>>
《代码大全》学习摘要(五)软件构建中的设计(下)
查看>>
C#检测驱动是否安装的问题
查看>>
web-4. 装饰页面的图像
查看>>
微信测试账户
查看>>
Android ListView上拉获取下一页
查看>>
算法练习题
查看>>
学习使用Django一 安装虚拟环境
查看>>
Hibernate视频学习笔记(8)Lazy策略
查看>>
CSS3 结构性伪类选择器(1)
查看>>
IOS 杂笔-14(被人遗忘的owner)
查看>>
自动测试用工具
查看>>
前端基础之BOM和DOM
查看>>
[T-ARA/筷子兄弟][Little Apple]
查看>>