2

ユーザー入力の検証が行われるログイン画面があり、ユーザーは認証され、最終的にウェルカム画面にリダイレクトされます。

以下は、 のインターセプター定義です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)
4

3 に答える 3

4
  1. execAndWaitアクションが新しいスレッドで実行されるようにします。
  2. ActionContextはであるためThreadLocal、新しいスレッドは の親スレッド バージョンに格納されている値を取得しません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);
    }

}
于 2013-11-13T21:37:09.547 に答える
3

NPEインターセプターを使用したアクションがexecAndWait別のスレッドで実行されており、getTextを使用するメソッドを呼び出しているために発生していますActionContextActionContextスレッド ローカルです。つまり、ActionContext に格納されている値はスレッドごとに一意です。

プロセスが終了した後に成功ページを表示するには、ページを時々更新する必要があります。では、で行われmeta http-equiv="refresh"ます。

<meta http-equiv="refresh" content="5;url=<s:url includeParams="all" />"/> 
于 2013-05-23T08:46:06.660 に答える
1

"error.login"アクションまたはアプリケーションで提供されたリソースにキーが見つからないか、間違ったロケールを使用しています。i18nこれは、リソースが構成されていないことを意味します。問題を解決するにLoginAction.propertiesは、ファイルを作成してその中にキーを入れる必要があります

error.login = Error login

投稿に表示されないグローバル プロパティ ファイルを使用している場合は、このキーをそこに追加します。

于 2013-05-22T15:33:15.403 に答える