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 ...
随机推荐
- KK的新书《必然》对未来科技趋势的预言
是他第一次在<失控>中提示我们-- 要用生物学而不是机械学的角度看待这个世界. 是他第一次在<科技想要什么>提示我们-- 科技本身就是一个生命体. 而在新书<必然 ...
- 可恶的0x1A
很少用fread读文件,今天用fread读一个文件死活缺一点,折腾半天才发现原来遇到0x1a. 0x1a 是 Ctrl+Z ,是模拟文件结束的符号,就是文件遇到0x1a后,认为文件已经结束. 哎!记下
- (转载)vsftpd简易配置
(转载)http://licong.blog.51cto.com/542131/145748/ 写篇关于vsftp配置的文章,加深自己的记忆,便于自己查阅,同时也希望能给其他需要的朋友一点借鉴.本文如 ...
- LoadRunner的场景设置
loadrunner场景设置的方法: 1.逐步增加用户数,分多次去运行场景.比如:第一次运行50并发,第二次运行100并发…… 2.针对同一个脚本设置多个组,使用组策略(点击Edit Schedule ...
- JavaScript 类型判断 —— typeof 以及 instanceof 中的陷阱
JavaScript中基本类型包含Undefined.Null.Boolean.Number.String以及Object引用类型.基本类型可以通过typeof来进行检测,对象类型可以通过instan ...
- 传统IO与NIO区别二
nio是new io的简称,从jdk1.4就被引入了.现在的jdk已经到了1.6了,可以说不是什么新东西了.但其中的一些思想值得我来研究.这两天,我研究了下其中的套接字部分,有一些心得,在此分享. ...
- android edittext 点击回车会响应两次的解决方案
由于Key有Down和Up事件,所以会执行两次. class editTextOnKeyClickListener implements etOnKeyClickListener { @Overrid ...
- OCCI处理CHAR类型字符串变量的不同
问题背景: 一个旧应用,原先应用是用proc写的,9i的库,如今应用须要改为使用OCCI,当中有一段查询逻辑:select ... where upper(state)=upper(:1). (此处请 ...
- 经典SQL语句大全之提升
二.提升 1.说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)法一:select * into b from a where 1<>1(仅用于SQlServer)法 ...
- 吧php脚本打包成 exe程序
操作方法 :FQ哦 https://www.youtube.com/watch?v=UQ3zxqh1YXY 有很多方法可以实现 找了个外国的哥们制作的工具 可以吧文件生成很简单的一个独立EXE文件 下 ...