struts2 - execAndWait 拦截器在等待后不重定向到成功页面

标签 struts2 struts-validation struts2-interceptors

我有一个登录屏幕,其中会进行一些用户输入验证,用户将通过身份验证并最终重定向到欢迎屏幕。

下面是 LoginAction 的拦截器定义:

<package name="default" extends="struts-default" namespace="/">
    <interceptors>  
        <interceptor name="myInterceptor" 
            class="com.interceptor.MyInterceptor"></interceptor>

        <interceptor-stack name="newStack">
            <interceptor-ref name="myInterceptor"/>             
            <interceptor-ref name="defaultStack" />
            <interceptor-ref name="execAndWait">
                <param name="delay">100</param>
                <param name="delaySleepInterval">500</param>
            </interceptor-ref>              
         </interceptor-stack> 
    </interceptors>

    <action name="login"
        class="com.action.LoginAction"> 
        <interceptor-ref name="newStack"/>
        <result name="success">common/Welcome.jsp</result>
        <result name="wait">common/wait.jsp</result>
        <result name="error">Login.jsp</result>
        <result name="input">Login.jsp</result>
    </action>
</package>

下面是LoginAction的执行方法:

   if (isUserAuthenticated) {
        // Some background processing for logging purpose           
        return "success";
    } else {            
        addActionError(getText("error.login"));
        return "error";
    }

这段代码有几个问题:

1) 对于经过身份验证的用户,将显示 wait.jsp 页面,但不会重定向到 Welcome.jsp

2) 对于未经身份验证的用户,我收到以下异常:

java.lang.NullPointerException
at com.opensymphony.xwork2.util.LocalizedTextUtil.findText(LocalizedTextUtil.java:361)
at com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:208)
at com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:123)
at com.opensymphony.xwork2.ActionSupport.getText(ActionSupport.java:103)
at com.infy.action.LoginAction.execute(LoginAction.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:450)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:289)
at org.apache.struts2.interceptor.BackgroundProcess$1.run(BackgroundProcess.java:57)
at java.lang.Thread.run(Thread.java:662)

最佳答案

  1. execAndWait 导致操作在新线程中执行。
  2. 由于 ActionContextThreadLocal,新线程将不会获取存储在 ActionContext 的父线程版本中的值。每个线程都有一个唯一版本的ActionContext
  3. getText() 尝试在新线程中执行时会抛出 NPE,因为它依赖于 ActionContext

要解决此问题,您需要将父线程 ActionContext 复制到 execAndWait 线程中。您可以通过扩展 BackgroundProcess 类、实现 beforeInvocation()afterInvocation() 方法以及扩展 ExecuteAndWaitInterceptor,实现 getNewBackgroundProcess() 方法。

示例

public class YourExecAndWaitInterceptor extends ExecuteAndWaitInterceptor {

    private static final long serialVersionUID = 1L;


    /**
     * {@inheritDoc}
     */
    @Override
    protected BackgroundProcess getNewBackgroundProcess(String arg0, ActionInvocation arg1, int arg2) {
        return new YourBackgroundProcess(arg0, arg1, arg2, ActionContext.getContext());
    }

}



public class YourBackgroundProcess extends BackgroundProcess {

    private final ActionContext context;

    public YourBackgroundProcess(String threadName, ActionInvocation invocation, int threadPriority, ActionContext context) {
        super(threadName, invocation, threadPriority);
        this.context = context;
     }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void beforeInvocation() {
        ActionContext.setContext(context);
    }

    /**
     * {@inheritDoc}
     */
   @Override
    protected void afterInvocation() {
        ActionContext.setContext(null);
    }

}

关于struts2 - execAndWait 拦截器在等待后不重定向到成功页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16692658/

相关文章:

java - 如何在 Struts 2 中动态传递带有 Action 名称的参数

java - 在 Struts 2 中重用自定义表达式 validator

java - struts2中不允许显示字段错误的拦截器

java - struts2中执行并等待拦截器

java - 为什么会出现这个未处理的 org.apache.tiles.impl.CannotRenderException?

jsp - Struts2 :label : Positions of label and value are inverted

java - 无法使用操作链和发布参数重定向到另一个 URL

validation - 在 Struts 2 中链接访问者验证器

java - 如何使用 Struts2 验证打印特定的操作错误消息?

exception - 为什么从我的拦截器引发的异常没有被 <global-exception-mappings> 捕获?