1

Interceptor を使用して struts2 アプリケーションでセッション タイムアウト リクエストを処理しようとしています。以下は、これに関連するファイルです。

Web.xml:

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
    <session-timeout>1</session-timeout>
</session-config>

Struts.xml:

<package name="default" extends="struts-default">
<interceptors>
    <interceptor name="sessionInterceptor"
        class="com.platform.web.security.SessionInterceptor" />
</interceptors>
<action name="doLogin"
    class="com.platform.web.action.LoginAction">
    <result name="input">/login/login.jsp</result>
    <result name="error">/login/login.jsp</result>
    <result type="chain">menuAction</result>
</action>

<action name="menuAction"
    class="com.platform.web.action.MenuAction">
    <interceptor-ref name="sessionInterceptor"/> //Interceptor included here
    <result name="SUCCESS">/jsp/main.jsp</result>
    <result name="ERROR">/login/login.jsp</result>
    <result name="input">/jsp/myFavourite.jsp</result>
</action>

インターセプター クラス:

public class SessionInterceptor extends AbstractInterceptor implements StrutsStatics {
/**
 * 
 */
private static final long serialVersionUID = 1L;

@Override
public String intercept(ActionInvocation invocation) throws Exception {

final ActionContext context = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context
    .get(HTTP_REQUEST);
HttpSession session = request.getSession(false);

// Is there a "user" object stored in the user's HttpSession?
//Object user = session.getAttribute("User");
if (session == null) {
    // The user has not logged in yet.

    // Is the user attempting to log in right now?
    //String loginAttempt = request.getParameter(LOGIN_ATTEMPT);

    /* The user is attempting to log in. */
    /*if (!StringUtils.isBlank(loginAttempt)) {
    return invocation.invoke();
    }*/
    return "timeout";
 } else {
    return invocation.invoke();
 }
 }
}

ログインアクション:

public class LoginAction extends MesActionSupport implements ServletRequestAware {
@Override
public String execute() throws Exception {
setActionNameForAudit("execute123");
FILE_LOGGER.debug("Entering into execute() ... ");
String strSessionId = "";

if (isValidUser == true) {
    user = getUser();

    strSessionId = request.getSession(true).getId();
    setServletRequest(request);
    session.put("SessionId", strSessionId);

    setSession(session, user);

    ServletActionContext.getRequest().getSession().setAttribute("User", user);

    FILE_LOGGER.debug("Exit from  LoginAction.execute() ... ");
    return SUCCESS;
} else {
    return ERROR;
}
 }

メニューアクション:

public class MenuAction extends MesActionSupport implements SessionAware, ParameterAware, RequestAware {
@Override
public String execute() throws Exception {
setActionNameForAudit("execute ");
User user = null; // To store current user
Map<String, ArrayList<String>> category = null; // To store all Menu
// Categories.
StringBuffer menu = new StringBuffer(""); // To store Menu String
StringBuffer dashboardMenu = new StringBuffer("");

// user = (User)(request.getSession().getAttribute("User")==null ? null : request.getSession().getAttribute("User")); //Request object IS NULL HERE!!
user = (User) (mapSession.get("User") == null ? null : mapSession
    .get("User")); // mapSession object IS NULL HERE
FILE_LOGGER.debug("user is " + user == null);

if (user != null) {
    menu = menuView.getMenu(user);
    mapSession.put("Menu", menu.toString());
    mapSession.put("dbMenu", dashboardMenu.toString());
    ret = "SUCCESS";
} else if (user == null) {
    ret = ERROR;
} else {
    ret = SUCCESS;
}
return ret;
}

フローは次のようになります。 1. ログイン画面が開きます 2. ユーザーが資格情報を入力して送信します 3. LoginAction が呼び出され、ユーザーが認証されます 4. 有効なユーザーの場合、MenuAction が呼び出されます。それ以外の場合は、Login.jsp にリダイレクトします

上記のコードによると、LoginAction でセッションが作成され、制御が Interceptor に到達し、そこでセッション オブジェクトがチェックされます。セッションが存在する場合、コントロールは MenuAction に到達します。

しかし、これが発生すると、requestオブジェクトは NULL にリセットされます! インターセプターを使用していなかった以前は、フローは LoginAction と MenuAction の間で完全に正常に機能していました。

インターセプターは HTTPRequest をリセットしますか? したがって、セッション?結果、先に進めません。

何か助けはありますか?

4

2 に答える 2

16

このコード/構成について多くのコメントがありますが、些細なこともあれば、そうでないこともあります。

  1. 独自のセッションを作成する理由はありません。しないでください。

  2. アクション構成でインターセプターを宣言するときは、すべてのインターセプターを宣言する必要があります。構成されているように、セッションインターセプターのみmenuActionが実行されています。

  3. これは、他のインターセプターが実行されていないため、パラメーターが入力されないことを意味します。

  4. SessionAware一般に、セッションにアクセスするためにのみ使用します。リクエストに直接アクセスする必要はほとんどありません。

  5. 明らかに、インターセプターは「要求をnullに設定」しません。これは、意味がありません。

  6. 私はあなたが何をしているのか分かりませんLoginAction。またはのような行の意図は何ですか?正しく見えるこれらの2行については何もありません。setServletRequest(request);setSession(session, user);

  7. 成功とエラーの結果にその名前を付けます。定数とを使用する場合は"success""error"(小文字で)名前を付けます。このコードでこれらの定数を使用していない場合は、他の名前を使用することをお勧めします。これは、以前にStruts2を実際に使用したことがある人を混乱させるためです。ActionSupport.SUCCESSActionSupport.ERROR

  8. コードサンプルを投稿するときは、関係のないものを削除してください。特に、構文の強調表示を明示的に設定しないと、読みにくくなります

  9. のようなコードは使用しないでください。if (isValidUser == true)を使用してくださいif (isValidUser)

  10. 条件に注意してください。次のようなものif (user == null) ... else if (user != null) ... else ...は意味がありません。ユーザーがnullであるか、そうでないか:3番目のオプションはありません。

  11. User currentUser = (User) (mapSession.get("User") == null ? null : mapSession.get("User"));基本的に「nullの場合はnullを使用し、そうでない場合は取得した値を返しますが、再度取得する」など、不要で紛らわしいロジックは避けてください。どうして???

  12. のようなコメントUser user = null; // To store current userは完全に無価値です。何なのかわかりませんUser userか?ユーザー。十分に明白ではありませんか?どうですかUser currentUser???

  13. 複数形(コレクションなど)に複数形の名前を付けます。カテゴリ名からリストへのマップは、単一のカテゴリではありません。

  14. 変数が使用されている場所から遠く離れた場所で変数を宣言しないでください。それは非常に紛らわしいです。

  15. JSPページをWEB-INFどこかに置いて、クライアントからの直接アクセスを禁止します。

  16. ifブランチが戻るときのように、不必要な言語構造を避けてくださいelse。厳密には必要ではありません。IMOは、ノイズを追加します。同様に、戻ってきたことがわかったらすぐに戻ることを検討してください。後者はもう少し物議をかもしますが、人々は短い方法で複数のリターンポイントを持っていても大丈夫だと気づき始めていると思います。IMOは考えやすいです。

  17. 物事を言うために少ないコードを使用してください。メインラインコードを汚染しないように、些細な機能をまとめるための小さなユーティリティメソッドを作成します。

  18. アクションチェーンを使用することはほとんどありません。

まだまだありますが、今のところはそれで十分です。クリーンアップされた実際の関連コードは次のとおりです。一部は実際には関係ありませんが、とにかくそのままにしておきました。


<filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<session-config>
  <session-timeout>1</session-timeout>
</session-config>
<package name="default" extends="struts-default">
  <interceptors>
    <interceptor name="sessionInterceptor" class="com.platform.web.security.SessionInterceptor" />
  </interceptors>

  <action name="doLogin" class="com.platform.web.action.LoginAction">
    <result name="input">/WEB-INF/jsp/login/login.jsp</result>
    <result name="error">/WEB-INF/jsp/login/login.jsp</result>
    <result type="redirectAction">menuAction</result>
  </action>

  <action name="menuAction" class="com.platform.web.action.MenuAction">
    <interceptor-ref name="sessionInterceptor"/>
    <result name="success">/WEB-INF/jsp/main.jsp</result>
    <result name="input">/WEB-INF/jsp/myFavourite.jsp</result>
  </action>
 public class SessionInterceptor extends AbstractInterceptor implements StrutsStatics {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        ActionContext context = invocation.getInvocationContext();
        HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
        HttpSession session = request.getSession(false);

        // session will almost *never* be null. Check for a valid user object.
        if (session == null) {
            return "timeout";
        }

        return invocation.invoke();
    }
}
public class LoginAction extends MesActionSupport implements ServletRequestAware {
    @Override
    public String execute() throws Exception {
        if (!isValidUser) {
            return ERROR;
        }

        user = getUser();

        String strSessionId = request.getSession(true).getId();
        setServletRequest(request);
        session.put("SessionId", strSessionId);

        setSession(session, user);

        ServletActionContext.getRequest().getSession().setAttribute("User", user);

        return SUCCESS;
    }
}
public class MenuAction extends MesActionSupport implements SessionAware, ParameterAware, RequestAware {
    @Override
    public String execute() throws Exception {
        User currentUser = (User) mapSession.get("User");
        if (currentUser == null) {
            return ERROR;
        }

        Map<String, List<String>> categories; // Left in for naming.

        StringBuffer menu = menuView.getMenu(user);
        mapSession.put("Menu", menu.toString());

        StringBuffer dashboardMenu = new StringBuffer("");
        mapSession.put("dbMenu", dashboardMenu.toString());

        return SUCCESS;
    }
}
于 2013-02-06T14:40:14.830 に答える
2

フロントエンドにトラッキングを追加しない限り、セッションがタイムアウトしたのか、インターセプターでまだ作成されていないのかを判断する方法はありません。基本的な場合は、単一のリクエストパラメーターである可能性があります。

HttpSessionListenerServlet3+AJAXプッシュ通知の組み合わせがそれを行う正しい方法です。

于 2013-02-06T19:50:28.573 に答える