使用 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异常的原因和解决方法的更多相关文章

  1. 在Eclipse中运行Jboss时出现java.lang.OutOfMemoryError:PermGen space及其解决方法

    在Eclipse中运行Jboss时出现java.lang.OutOfMemoryError:PermGen space及其解决方法 在Eclipse中运行Jboss时,时间太长可能有时候会出现java ...

  2. 解决 spring boot 线程中使用@Autowired注入Bean的方法,报java.lang.NullPointerException异常

    问题描述 在开发中,因某些业务逻辑执行时间太长,我们常使用线程来实现.常规服务实现类中,使用 @Autowired 来注入Bean,来调用其中的方法.但如果在线程类中使用@Autowired注入的Be ...

  3. td中不包含汉字的字符串不换行,包含汉字的能换行的问题原因及解决方法

    今天项目中遇到一个问题,一长串的字符串如:003403FF0014E54016030CC655BC3242,但是如:中国河北省石家庄市裕华区槐安路雅清街交口 这样的就可以换行. 原因是:英文字母之间如 ...

  4. Android ADT插件更新后程序运行时抛出java.lang.VerifyError异常解决办法

    当我把Eclipse中的 Android ADT插件从21.1.0更新到22.0.1之后,安装后运行程序抛出java.lang.VerifyError异常. 经过调查,终于找到了一个有效的解决办法: ...

  5. [hadoop] map函数中使用FileSystem对象出现java.lang.NullPointerException的原因及解决办法

    问题描述: 在hadoop中处理多个文件,其中每个文件一个map. 我使用的方法为生成一个文件,文件中包含所有要压缩的文件在HDFS上的完整路径.每个map 任务获得一个路径名作为输入. 在eclip ...

  6. 轻松搞定项目中的空指针异常Caused by: java.lang.NullPointerException: null

    大家在项目测试过程中,是不是经常会碰到这个空指针异常呢Caused by: java.lang.NullPointerException: null 当大家遇到这个问题,大家是怎么处理?自己解决还是让 ...

  7. struts2:数据校验,通过Action中的validate()方法实现校验,图解

    根据输入校验的处理场所的不同,可以将输入校验分为客户端校验和服务器端校验两种.服务器端验证目前有两种方式: 第一种 Struts2中提供了一个com.opensymphony.xwork2.Valid ...

  8. struts2:数据校验,通过Action中的validate()方法实现校验(续:多业务方法时的不同验证处理)

    前文:struts2:数据校验,通过Action中的validate()方法实现校验,图解 如果定义的Action中存在多个逻辑处理方法,且不同的处理逻辑可能需要不同的校验规则,在这种情况下,就需要通 ...

  9. Struts2学习(二)运行Action中方法的三种方式

    1.运行execute()方法 一般的能够直接在action中书写execute,调用action时会自己主动运行此方法 2.配置method方法 在struts.xml中配置action时.写met ...

随机推荐

  1. BZOJ4195 [Noi2015]程序自动分析(离散化+并查集)

    4195: [Noi2015]程序自动分析 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 689  Solved: 296 [Submit][Sta ...

  2. mac上的键盘生活——打字训练

    我的打字真的很有问题,错误率实在是太高了,于是乎下定决心改掉打字习惯,起码为了对得起我的机械键盘   所谓双击键(shift)就是当一个键钮上有两个字符时的辅助选择键,像标注在数字1上的 !,就是在你 ...

  3. codeforces 385C Bear and Prime Numbers 预处理DP

    题目链接:http://codeforces.com/problemset/problem/385/C 题目大意:给定n个数与m个询问区间,问每个询问区间中的所有素数在这n个数中被能整除的次数之和 解 ...

  4. C# SQL 整表插入 分类: C# 2014-09-17 16:18 369人阅读 评论(2) 收藏

    说明: (1)表A的一部分数据插入到表B (2)DataAccess 类,是放在DAL层下的底层类; da.StrConnection 写在DataAccess类中; //整表插入方法 private ...

  5. BootStrap-table 客户端分页和服务端分页的区别

    当服务器没有对数据进行分页时,前端页面设计又要求进行分页,要分开来设置. 服务端分页: responseHandler: function(data){ return data.response; } ...

  6. Unity3d UnityEditor EditorWindow 自定义窗体控件

    功能:是因为公司的模型组需要一个插件,在MAYA中有很多个复制物体,导出的时候只导出一个,其他相同的物体只导出点的位置信息.这样进入Unity里就是一个物体和N个相同物体的位置点,代码简单但是需要用插 ...

  7. OS开发网络篇—监测网络状态

    iOS开发网络篇—监测网络状态 一.说明 在网络应用中,需要对用户设备的网络状态进行实时监控,有两个目的: (1)让用户了解自己的网络状态,防止一些误会(比如怪应用无能) (2)根据用户的网络状态进行 ...

  8. Unity UGUI——Rect Transform组件(基础属性)

    基础属性:Width.Height.Pivot图示 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfQUhhbw==/font/5a6L5L2T/fo ...

  9. golang 学习笔记

    golan 声明的变量必须要用到? 语法 a,b:=2323; b为 bool 类型 结构体的赋值 需要用到逗号分隔字段 并且最后一个字段后也必须加上逗号 这和 JavaScript 的对象不一样哦 ...

  10. android 25 跨进程启动activity

    跨进程启动activity,启动系统预定义的activity就是跨进程的. client项目启动server项目的activity. clientActivity.java package com.s ...