Struts2中使用execAndWait后,在 Action中调用getXXX()方法报告java.lang.NullPointerException异常的原因和解决方法
使用 Struts2 编写页面,遇到一个要长时间运行的接口,因此增加了一个execAndWait ,结果在 Action 中调用 getContext()的时候报告异常
ActionContext context = ActionContext.getContext();
ServletContext servletContext = (ServletContext) context.get(ServletActionContext.SERVLET_CONTEXT); //抛空指针异常
String rootPath = servletContext.getRealPath("/");
查询了很多评论,最终找到原因跟解决方案,具体解释在 http://stackoverflow.com/questions/16692658/execandwait-interceptor-not-redirecting-to-success-page-after-waiting。大致意思为:execAndWait 会导致执行的Action 在另外一个线程中被执行,而getText 依赖 ActionContext ,他从 ActionContext 中获得当前的Locale 从而根据语言的不同加载不同的文字,可是,由于ActionContext 是ThreadLocal 的,而execAndWait 新开线程的时候并没有把父线程的ActionContext 传递给子线程 结果导致在新开的子线程中的ActionContext中的数据都是null ,因此出现异常信息就不足为怪了。
解决方法如下:需要重载两个类,来解决这个问题
ActionInvocationEx.java
package byrs.rms.interceptors; import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionEventListener;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.interceptor.PreResultListener;
import com.opensymphony.xwork2.util.ValueStack; public class ActionInvocationEx implements ActionInvocation { /**
*
*/
private static final long serialVersionUID = 2434502343414625665L; private final ActionInvocation mActionInvocation; private final ActionContext context; public ActionInvocationEx(ActionInvocation aActionInvocation,ActionContext aContext)
{
mActionInvocation = aActionInvocation;
context = aContext;
} public Object getAction() {
return mActionInvocation.getAction();
} public boolean isExecuted() {
return mActionInvocation.isExecuted();
} public ActionContext getInvocationContext() {
return mActionInvocation.getInvocationContext();
} public ActionProxy getProxy() {
return mActionInvocation.getProxy();
} public Result getResult() throws Exception {
return mActionInvocation.getResult();
} public String getResultCode() {
return mActionInvocation.getResultCode();
} public void setResultCode(String resultCode) {
mActionInvocation.setResultCode(resultCode);
} public ValueStack getStack() {
return mActionInvocation.getStack();
} public void addPreResultListener(PreResultListener listener) {
mActionInvocation.addPreResultListener(listener);
} public String invoke() throws Exception {
return mActionInvocation.invoke();
} public String invokeActionOnly() throws Exception {
return mActionInvocation.invokeActionOnly();
} public void setActionEventListener(ActionEventListener listener) {
mActionInvocation.setActionEventListener(listener);
} public void init(ActionProxy proxy) {
mActionInvocation.init(proxy);
} public ActionInvocation serialize() {
return mActionInvocation.serialize();
} public ActionInvocation deserialize(ActionContext actionContext) {
return mActionInvocation.deserialize(actionContext);
} /**
* @return the context
*/
public ActionContext getContext() {
return context;
} }
ExecAndWaitInterceptorEx.java
package byrs.rms.interceptors; import org.apache.struts2.interceptor.BackgroundProcess;
import org.apache.struts2.interceptor.ExecuteAndWaitInterceptor; import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation; public class ExecAndWaitInterceptorEx extends ExecuteAndWaitInterceptor { /**
*
*/
private static final long serialVersionUID = 8829373762598564300L; /**
* {@inheritDoc}
*/
@Override
protected BackgroundProcess getNewBackgroundProcess(String arg0, ActionInvocation arg1, int arg2) {
ActionInvocationEx aActionInvocationEx = new ActionInvocationEx(arg1,ActionContext.getContext());
return new BackgroundProcessEx(arg0, aActionInvocationEx, arg2);
} private class BackgroundProcessEx extends BackgroundProcess {
public BackgroundProcessEx(String threadName,
ActionInvocation invocation, int threadPriority) {
super(threadName, invocation, threadPriority);
} private static final long serialVersionUID = -9069896828432838638L;
/**
* {@inheritDoc}
* @throws InterruptedException
*/
@Override
protected void beforeInvocation() throws InterruptedException {
ActionInvocationEx aActionInvocationEx = (ActionInvocationEx)this.invocation;
ActionContext context = aActionInvocationEx.getContext();
ActionContext.setContext(context);
} /**
* {@inheritDoc}
*/
@Override
protected void afterInvocation() {
ActionContext.setContext(null);
} } }
然后在struts.xml中覆盖默认拦截器即可
<interceptors >
<interceptor name="execAndWait" class="byrs.rms.interceptors.ExecAndWaitInterceptorEx"/>
</interceptors >
参考自:http://www.mobibrw.com/?p=1046
Struts2中使用execAndWait后,在 Action中调用getXXX()方法报告java.lang.NullPointerException异常的原因和解决方法的更多相关文章
- 在Eclipse中运行Jboss时出现java.lang.OutOfMemoryError:PermGen space及其解决方法
在Eclipse中运行Jboss时出现java.lang.OutOfMemoryError:PermGen space及其解决方法 在Eclipse中运行Jboss时,时间太长可能有时候会出现java ...
- 解决 spring boot 线程中使用@Autowired注入Bean的方法,报java.lang.NullPointerException异常
问题描述 在开发中,因某些业务逻辑执行时间太长,我们常使用线程来实现.常规服务实现类中,使用 @Autowired 来注入Bean,来调用其中的方法.但如果在线程类中使用@Autowired注入的Be ...
- td中不包含汉字的字符串不换行,包含汉字的能换行的问题原因及解决方法
今天项目中遇到一个问题,一长串的字符串如:003403FF0014E54016030CC655BC3242,但是如:中国河北省石家庄市裕华区槐安路雅清街交口 这样的就可以换行. 原因是:英文字母之间如 ...
- Android ADT插件更新后程序运行时抛出java.lang.VerifyError异常解决办法
当我把Eclipse中的 Android ADT插件从21.1.0更新到22.0.1之后,安装后运行程序抛出java.lang.VerifyError异常. 经过调查,终于找到了一个有效的解决办法: ...
- [hadoop] map函数中使用FileSystem对象出现java.lang.NullPointerException的原因及解决办法
问题描述: 在hadoop中处理多个文件,其中每个文件一个map. 我使用的方法为生成一个文件,文件中包含所有要压缩的文件在HDFS上的完整路径.每个map 任务获得一个路径名作为输入. 在eclip ...
- 轻松搞定项目中的空指针异常Caused by: java.lang.NullPointerException: null
大家在项目测试过程中,是不是经常会碰到这个空指针异常呢Caused by: java.lang.NullPointerException: null 当大家遇到这个问题,大家是怎么处理?自己解决还是让 ...
- struts2:数据校验,通过Action中的validate()方法实现校验,图解
根据输入校验的处理场所的不同,可以将输入校验分为客户端校验和服务器端校验两种.服务器端验证目前有两种方式: 第一种 Struts2中提供了一个com.opensymphony.xwork2.Valid ...
- struts2:数据校验,通过Action中的validate()方法实现校验(续:多业务方法时的不同验证处理)
前文:struts2:数据校验,通过Action中的validate()方法实现校验,图解 如果定义的Action中存在多个逻辑处理方法,且不同的处理逻辑可能需要不同的校验规则,在这种情况下,就需要通 ...
- Struts2学习(二)运行Action中方法的三种方式
1.运行execute()方法 一般的能够直接在action中书写execute,调用action时会自己主动运行此方法 2.配置method方法 在struts.xml中配置action时.写met ...
随机推荐
- TCP Socket的通讯框架
http://www.oschina.net/p/simple-socketshttp://www.oschina.net/p/cwsshttp://www.oschina.net/p/tcpprox ...
- implicitly_wait()隐式等待
# -*- coding:utf-8 -*- """ implicitly_wait():隐式等待 当使用了隐士等待执行测试的时候,如果 WebDriver没有在 DOM ...
- Django中的Form
Form 一.使用Form Django中的Form使用时一般有两种功能: 1.生成html标签 2.验证输入内容 要想使用django提供的form,要在views里导入form模块 from dj ...
- mysql登录时,ERROR 1045 (28000): 错误解决办法
错误问题的描述: ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO) ERROR 10 ...
- Palindrome - URAL - 1297(求回文串)
题目大意:RT 分析:后缀数组求回文串,不得不说确实比较麻烦,尤其是再用线段数进行查询,需要注意的细节地方比较多,比赛实用性不高......不过练练手还是可以的. 线段数+后缀数组代码如下: ...
- linux常用命令大全(转)
由于记忆力有限,把平时常用的Linux命令整理出来,以便随时查阅: linux 基本命令 ls (list 显示当前目录下文件和目录 ls -l 详细显示 =ll ) [root@linux ...
- Spring三 Bean的三种创建方式
创建Bean的三种方式在大多数情况下,Spring容器直接通过new关键字调用构造器来创建Bean实例,而class属性指定Bean实例的实现类,但这不是实例化Bean的唯一方法.实际上,Spring ...
- .htaccess文件的妙用
.htaccess是Apache HTTP Server系统级别的配置文件,通常用来实现主机本身以外的一些功能的,比如说重定向.Gzip.以及访问限制等等………… 1.重定向(301跳转) 相信这个功 ...
- linux —— shell 编程(编程语法)
导读 本文为博文linux —— shell 编程(整体框架与基础笔记)的第4小点的拓展.(本文所有语句的测试均在 Ubuntu 16.04 LTS 上进行) 目录 再识变量 函数 条件语句 循环语句 ...
- 索引查找(索引查找、分块查找) C语言实现
1.基本概念 索引查找又称分级查找. 索引存储的基本思想是:首先把一个集合或线性表(他们对应为主表)按照一定的函数关系或条件划分成若干个逻辑上的子表,为每个子表分别建立一个索引项,由所有 这些索引项构 ...