java actioncontext_关于struts2中ActionContext的实现原理

java actioncontext_关于struts2中ActionContext的实现原理北京,雾霾天气阻止了今天的马拉松之行,蜗居一天。为一个问题“struts2如何保证ActionContext每次取的都是本次请求所对应的实例?”,给一个网友解释了半天。首先,我们知道,struts2和struts1的一个重要区别就是它进行了Action类和Servlet的解耦。而又提供了获取ServletAPI的其它通道,就是ActionContext(别跟我说还有个ServletActionC…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

北京,雾霾天气阻止了今天的马拉松之行,蜗居一天。为一个问题“struts2如何保证ActionContext每次取的都是本次请求所对应的实例?”,给一个网友解释了半天。

首先,我们知道,struts2和struts1的一个重要区别就是它进行了Action类和Servlet的解耦。而又提供了获取Servlet API的其它通道,就是ActionContext(别跟我说还有个ServletActionContext,其实ServletActionContext只是ActionContext的一个子类而已)。源码为证:public class ServletActionContext extends ActionContext implements StrutsStatics

其次,他也知道,ActionContext是Action执行时的上下文,可以看作是一个容器,并且这个容器只是一个Map而已,在容器中存放的是Action在执行时需要用到的VALUE_STACK、ACTION_NAME、SESSION、APPLICATION、ACTION_INVOCATION等等对象,还可以存放自定义的一些对象。我想用过struts2的朋友们,大多也都知道这些吧。

第三,他奇怪的是,在一个请求的处理过程拦截器、action类和result中任何时候获取的ActionContext都是跟当前请求绑定那一个。为什么!?

我给他的建议是,带着问题读源码,呵呵。那我们一起来看看吧:

首先是ActionContext类的源码:public class ActionContext implements Serializable{

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”;

Map context;

public ActionContext(Map context)

{

this.context = context;

}

//… …

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 this.context;

}

//… …

public void setSession(Map session)

{

put(“com.opensymphony.xwork2.ActionContext.session”, session);

}

public Map getSession()

{

return (Map)get(“com.opensymphony.xwork2.ActionContext.session”);

}

//… …

public Object get(String key)

{

return this.context.get(key);

}

public void put(String key, Object value)

{

this.context.put(key, value);

}

}

源码清晰的说明了我们编程中再熟悉不过的一行代码:ActionContext ctx = ActionContext.getContext();,原来我们所取得的ctx来自于ThreadLocal啊!熟悉ThreadLocal的朋友都知道它是与当前线程绑定的,而且是我们Java中处理多线程问题的一种重要方式。我们再看,类中有个Map类型的变量context,其实,它才是前面我们提到的真正意义上的“容器”,用来存放Action在执行时所需要的那些数据。

到这里,他最初的那个问题已经很了然了。但是,他紧接着又一个疑惑提出来了:“那既然每个请求处理线程都有自己的ActionContext,那里面的那些数据是什么时候放进去的呢”?

这次我给他的建议是,动脑筋,用源码验证。既然ActionContext存放有HttpServletRequest及其中的参数,既然ActionContext贯穿于整个请求处理过程,那就从struts2请求处理的入口(过滤器StrutsPrepareAndExecuteFilter)找,源码:public class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter

{

// … …

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)

throws IOException, ServletException

{

HttpServletRequest request = (HttpServletRequest)req;

HttpServletResponse response = (HttpServletResponse)res;

try

{

this.prepare.setEncodingAndLocale(request, response);

this.prepare.createActionContext(request, response);//就是在这里进行创建并初始化ActionContext实例

this.prepare.assignDispatcherToThread();

if ((this.excludedPatterns != null) && (this.prepare.isUrlExcluded(request, this.excludedPatterns))) {

chain.doFilter(request, response);

} else {

request = this.prepare.wrapRequest(request);

ActionMapping mapping = this.prepare.findActionMapping(request, response, true);

if (mapping == null) {

boolean handled = this.execute.executeStaticResourceRequest(request, response);

if (!handled)

chain.doFilter(request, response);

}

else {

this.execute.executeAction(request, response, mapping);

}

}

} finally {

this.prepare.cleanupRequest(request);

}

}

//… …

}

再找到prepare对应的类PrepareOperations,查看方法createActionContext(),就一目了然了。

对于ServletActionContext作为ActionContext一个直接子类,原理也是类似的,感兴趣的朋友可以看一下。

帮助别人,同时也是帮助自己。把这个处理的过程记录下来,希望对需要的朋友有所帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/195570.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 约瑟夫环问题递归解法的一点理解

    约瑟夫环问题递归解法的一点理解约瑟夫环递归解法代码的一点理解。约瑟夫生者死者游戏约瑟夫游戏的大意:30个游客同乘一条船,因为严重超载,加上风浪大作,危险万分。因此船长告诉乘客,只有将全船一半的旅客投入海中,其余人才能幸免于难。无奈,大家只得同意这种办法,并议定30个人围成一圈,由第一个人数起,依次报数,数到第9人,便把他投入

  • Java内存管理-一文掌握虚拟机创建对象的秘密(九)

    勿在流沙筑高台,出来混迟早要还的。做一个积极的人编码、改bug、提升自己我有一个乐园,面向编程,春暖花开!回顾一下:本文是接着上一篇内容:Java内存管理-愚人节new一个对象送给你(八),继续整理!主要内容讲解HotSpot虚拟机在Java堆中对象是如何创建、内存分配布局和访问方式。本文地图:一、给你创建一个对象如果你是一直从第一季看过来的,那一定知道前面有个地方讲过类的整…

  • 安卓ExpandableListView的详细使用教程(附代码解析过程)

    安卓ExpandableListView的详细使用教程(附代码解析过程)ExpandableListView又称可扩展的ListView,它可以实现点击父项展开子项的效果,本文实现了一个比较精美的ExpandableListView。

  • pycharm中pyqt5使用方法_pycharm安装pyqt5失败

    pycharm中pyqt5使用方法_pycharm安装pyqt5失败1.安装第pyqt5pipinstallpyqt52.QtDesigner安装和使用pipinstallpyqt5-tools3.UI文件转换成py文件$FileName$-o$FileNameWithoutExtension$.py-x4.将QRC资源文件转换成py文件$FileName$-o$FileNameWithoutExtension$_rc.py5.测试5.1新建项目5.2新建UI界面5.3将QT设计师保

  • idea2021.11激活(注册激活)

    (idea2021.11激活)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html1M3Q9SD5XW-eyJsaWN…

  • 脑电独立成分分析(independent component analysis)「建议收藏」

    脑电独立成分分析(independent component analysis)「建议收藏」相比其它成像方法,EEG更为便捷低价,无论是拿erp成分还是做时频分析,提高信噪比始终是EEG分析的重点。将ICA应用在EEG分析中,可以较好的识别并去掉眼动和其它噪音(heartbeat,linenoise,musclenoise)。但对ICA分析前的预处理和后期成分的识别,缺少详细的说明。以下的分析方法主要参考EEGLAB给的非官方说明,tutorial的第九章和第十章,BoyLu…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号