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的新书《必然》对未来科技趋势的预言
是他第一次在<失控>中提示我们-- 要用生物学而不是机械学的角度看待这个世界. 是他第一次在<科技想要什么>提示我们-- 科技本身就是一个生命体. 而在新书<必然 ...
- Selenium如何实现dropbar移动
遇到这个拖拽的dropbar,如何实现呢,, 经过网上查找,可以用Action的方式实现或者js来控制 原理:移动按钮的同时,数字也随着变化 解决方法:1.最简单的就是直接在文本框输入相应的数字 2. ...
- mysql 引擎区分
MySQL常用的存储引擎为MyISAM.InnoDB.MEMORY.MERGE,其中InnoDB提供事务安全表,其他存储引擎都是非事务安全表. MyISAM是MySQL的默认存储引擎.MyISAM不支 ...
- 自动布局AutoLayout
1:理解概念 Auto Layout 中文翻译过来意思是 自动布局 ,通过内定的 Constraint (约束)和各项条件来计算出合理的布局.而这个合理的布局,符合我们的的预期和意图. 将我们想象中的 ...
- system2之:4-LVM逻辑卷管理
LVM有扩容功能,无容错功能 物理卷: [root@localhost ~]# pvscan PV /dev/sda2 VG VolGroup lvm2 [19.51 GiB / 0 ...
- DevExpress LookUpEdit 下拉框基本操作
<span style="font-size:14px;"> ArrayList list = new ArrayList(); //遍历皮肤,放到列表中 foreac ...
- 异常Address already in use: JVM_Bind的处理
如题,Address already in use: JVM_Bind这个异常的意思就是说jvm被占用了 那么大家一般的解决情况都是重启一下eclipse , 结果还是不行,结果就只能重启电脑了. 对 ...
- 【机房重构】SQL之视图
近期在重构机房收费系统,越往后就会越感觉到这里很多其它的是对之前学过知识(数据库,设计模式)的一种应用和回想.比方在登录功能中用到了抽象加反射,在学生下机中,我们能够用触发器来同一时候更新两个表.这里 ...
- java获取当前方法
1.获取当前方法堆栈,我们一般用 StackTraceElement[] stes = Thread.currentThread().getStackTrace(); 想要获取当前方法,切记不够灵活, ...
- Google技术专家的建议:各种SdkVersion如何选择?
原文链接: https://medium.com/google-developers/picking-your-compilesdkversion-minsdkversion-targetsdkver ...