execAndWait 拦截器在等待后不重定向到成功页面 [英] execAndWait Interceptor not redirecting to success page after waiting
问题描述
我有一个登录屏幕,其中会发生一些用户输入验证,用户将通过身份验证并最终重定向到欢迎屏幕.
I have a login screen where some user input validation will happen, the user will be authenticated and finally redirected to the welcome screen.
下面是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
的execute方法:
Below is the execute method of LoginAction
:
if (isUserAuthenticated) {
// Some background processing for logging purpose
return "success";
} else {
addActionError(getText("error.login"));
return "error";
}
我在使用此代码时遇到了一些问题:
I am having a couple of problems with this code:
1) 对于经过身份验证的用户,会显示 wait.jsp
页面,但不会重定向到 Welcome.jsp
.
1) For an authenticated user, the wait.jsp
page is getting displayed but the redirection to Welcome.jsp
is not happening.
2) 对于未经身份验证的用户,我收到以下异常:
2) for an unAuthenticated user, I am getting the below exception:
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)
推荐答案
execAndWait
导致在新线程中执行操作.- 由于
ActionContext
是ThreadLocal
,新线程将不会获取存储在ActionContext
的父线程版本中的值.每个线程都有一个唯一版本的ActionContext
getText()
尝试在新线程中执行时会抛出 NPE,因为它依赖于ActionContext
execAndWait
causes the action to be executed in a new thread.- Since
ActionContext
isThreadLocal
, the new thread will not get the values stored in the parent thread version ofActionContext
. Every thread has a unique version ofActionContext
getText()
will throw a NPE when it tries to execute in the new thread because it depends onActionContext
要解决此问题,您需要将父线程 ActionContext
复制到 execAndWait
线程中.您可以通过扩展 BackgroundProcess
类、实现 beforeInvocation()
和 afterInvocation()
方法以及扩展 ExecuteAndWaitInterceptor
来实现这一点code>,实现 getNewBackgroundProcess()
方法.
To fix this, you need to copy the parent threads ActionContext
into the execAndWait
thread. You can do this by extending the BackgroundProcess
class, implementing the beforeInvocation()
and afterInvocation()
methods, and extending ExecuteAndWaitInterceptor
, implementing the getNewBackgroundProcess()
method.
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);
}
}
这篇关于execAndWait 拦截器在等待后不重定向到成功页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!