zoukankan      html  css  js  c++  java
  • Struts2中使用execAndWait后,在 Action中调用getXXX()方法报告java.lang.NullPointerException异常的原因和解决方法

    使用 Struts2 编写页面,遇到一个要长时间运行的接口,因此增加了一个execAndWait ,结果在 Action 中调用 getContext()的时候报告异常

    1 ActionContext context = ActionContext.getContext();
    2 ServletContext servletContext = (ServletContext) context.get(ServletActionContext.SERVLET_CONTEXT);  //抛空指针异常
    3 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

     1 package byrs.rms.interceptors;
     2 
     3 import com.opensymphony.xwork2.ActionContext;
     4 import com.opensymphony.xwork2.ActionEventListener;
     5 import com.opensymphony.xwork2.ActionInvocation;
     6 import com.opensymphony.xwork2.ActionProxy;
     7 import com.opensymphony.xwork2.Result;
     8 import com.opensymphony.xwork2.interceptor.PreResultListener;
     9 import com.opensymphony.xwork2.util.ValueStack;
    10 
    11 public class ActionInvocationEx implements ActionInvocation {
    12 
    13     /**
    14      * 
    15      */
    16     private static final long serialVersionUID = 2434502343414625665L;
    17 
    18     private final ActionInvocation mActionInvocation;
    19 
    20     private final ActionContext context;
    21 
    22     public ActionInvocationEx(ActionInvocation aActionInvocation,ActionContext aContext)
    23     {
    24         mActionInvocation = aActionInvocation;
    25         context = aContext;
    26     }
    27 
    28     public Object getAction() {
    29         return mActionInvocation.getAction();
    30     }
    31 
    32     public boolean isExecuted() {
    33         return mActionInvocation.isExecuted();
    34     }
    35 
    36     public ActionContext getInvocationContext() {
    37         return mActionInvocation.getInvocationContext();
    38     }
    39 
    40     public ActionProxy getProxy() {
    41         return mActionInvocation.getProxy();
    42     }
    43 
    44     public Result getResult() throws Exception {
    45         return mActionInvocation.getResult();
    46     }
    47 
    48     public String getResultCode() {
    49         return mActionInvocation.getResultCode();
    50     }
    51 
    52     public void setResultCode(String resultCode) {
    53         mActionInvocation.setResultCode(resultCode);
    54     }
    55 
    56     public ValueStack getStack() {
    57         return mActionInvocation.getStack();
    58     }
    59 
    60     public void addPreResultListener(PreResultListener listener) {
    61         mActionInvocation.addPreResultListener(listener);
    62     }
    63 
    64     public String invoke() throws Exception {
    65         return mActionInvocation.invoke();
    66     }
    67 
    68     public String invokeActionOnly() throws Exception {
    69         return mActionInvocation.invokeActionOnly();
    70     }
    71 
    72     public void setActionEventListener(ActionEventListener listener) {
    73         mActionInvocation.setActionEventListener(listener);
    74     }
    75 
    76     public void init(ActionProxy proxy) {
    77         mActionInvocation.init(proxy);
    78     }
    79 
    80     public ActionInvocation serialize() {
    81         return mActionInvocation.serialize();
    82     }
    83 
    84     public ActionInvocation deserialize(ActionContext actionContext) {
    85         return mActionInvocation.deserialize(actionContext);
    86     }
    87 
    88     /**
    89      * @return the context
    90      */
    91     public ActionContext getContext() {
    92         return context;
    93     }
    94 
    95 }

    ExecAndWaitInterceptorEx.java

     1 package byrs.rms.interceptors;
     2 
     3 import org.apache.struts2.interceptor.BackgroundProcess;
     4 import org.apache.struts2.interceptor.ExecuteAndWaitInterceptor;
     5 
     6 import com.opensymphony.xwork2.ActionContext;
     7 import com.opensymphony.xwork2.ActionInvocation;
     8 
     9 public class ExecAndWaitInterceptorEx extends ExecuteAndWaitInterceptor {
    10 
    11     /**
    12      * 
    13      */
    14     private static final long serialVersionUID = 8829373762598564300L;
    15     
    16     /**
    17      * {@inheritDoc}
    18      */
    19     @Override
    20     protected BackgroundProcess getNewBackgroundProcess(String arg0, ActionInvocation arg1, int arg2) {
    21         ActionInvocationEx aActionInvocationEx = new ActionInvocationEx(arg1,ActionContext.getContext());
    22         return new BackgroundProcessEx(arg0, aActionInvocationEx, arg2);
    23     }
    24 
    25     private class BackgroundProcessEx extends BackgroundProcess {
    26         public BackgroundProcessEx(String threadName,
    27                 ActionInvocation invocation, int threadPriority) {
    28             super(threadName, invocation, threadPriority);
    29         }
    30 
    31         private static final long serialVersionUID = -9069896828432838638L;
    32         /**
    33          * {@inheritDoc}
    34          * @throws InterruptedException 
    35          */
    36         @Override
    37         protected void beforeInvocation() throws InterruptedException {
    38             ActionInvocationEx aActionInvocationEx = (ActionInvocationEx)this.invocation;
    39             ActionContext context = aActionInvocationEx.getContext();
    40             ActionContext.setContext(context);
    41         }
    42 
    43         /**
    44          * {@inheritDoc}
    45          */
    46        @Override
    47         protected void afterInvocation() {
    48             ActionContext.setContext(null);
    49         }
    50 
    51     }
    52 
    53 }

    然后在struts.xml中覆盖默认拦截器即可

    1 <interceptors > 
    2             <interceptor name="execAndWait" class="byrs.rms.interceptors.ExecAndWaitInterceptorEx"/> 
    3         </interceptors >

    参考自:http://www.mobibrw.com/?p=1046

  • 相关阅读:
    数学--数论--HDU 2136(素数筛选法)
    思维+模拟--POJ 1013 Counterfeit Dollar
    数学--数论--莫比乌斯函数
    事半功倍和事倍功半
    一道阿里面试题
    文本分类学习(三) 特征权重(TF/IDF)和特征提取
    汉字字典树
    文本分类学习(二)文本表示
    文本分类学习(一):开篇
    一道网易面试编程题
  • 原文地址:https://www.cnblogs.com/xiaochao-cs-whu/p/3720268.html
Copyright © 2011-2022 走看看