10

このトピックに関する多くの投稿を見てきましたが、私の場合はうまくいく解決策を得ることができませんでした.

JSF 2.0 で Java EE 6 を使用しています (JBoss AS 7.1 にデプロイ)

web.xmlは持っています:

    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

セッションが自動的にタイムアウトしたときに、ユーザーがログインページにリダイレクトされるようにします。

私が試したこと:

アプローチ 1: フィルターを使用する

次のフィルターを試しました。

@WebFilter()
public class TimeOutFilter implements Filter {

        @Override
        public void init(FilterConfig filterConfig) throws ServletException { 
        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
        ServletException {
        System.out.println("filter called");
        final HttpServletRequest req = (HttpServletRequest) request;
        final HttpSession session = req.getSession(false);
        if (session != null && !session.isNew()) {
            chain.doFilter(request, response);
        } else {
            System.out.println("Has timed out");
            req.getRequestDispatcher("/logon.xthml").forward(request, response);
        }
    }

    @Override
    public void destroy() {
    }
}

web.xml私が試した中で

<filter-mapping>
    <filter-name>TimeOutFilter</filter-name>
    <url-pattern>*.xhtml</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>TimeOutFilter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

フィルターは、すべての要求で呼び出されると機能します (コンソールに "fiter called" のログが記録されます)。ただし、セッションがタイムアウトしても呼び出されません。

アプローチ 2: HttpSessionLister

を使用しようとしましたHttpSessionListerner。次のシグネチャを持つメソッドが呼び出されます。

public void sessionDestroyed(HttpSessionEvent se) {
}

特定のページにリダイレクトできませんでした。ユーザーをリダイレクトしたいときは、通常NavigationHandlerfrom を使用しますFacesContextが、この場合はFacesContext( FacesContext.getCurrentInstance()return null) はありません。

この投稿によると、HttpListener はリクエストの一部ではないため、ユーザーをリダイレクトできません。

質問

この問題を解決する最善の方法は何ですか? 上記の 2 つのアプローチのいずれかを機能させるにはどうすればよいですか?

4

4 に答える 4

18

You can't send a HTTP response as long as the client hasn't send a HTTP request. Simple as that. That's just how HTTP works. The Internet would otherwise have looked very different if any website was able to unaskingly push a HTTP response without the client having requested for it.

A JavaScript based heartbeat based on client's keyboard/mouse activity like as answered here, or a meta refresh header like as answered here would be the solution if you've basically a single-page webapp (thus, you're effectively not using the session scope but the view scope), but that won't work nicely if you've the page open in multiple tabs/windows in the same session.

Websockets is in theory the right solution to push something to the client, but this requires in turn an active session. Chicken-Egg problem. Also, it wouldn't work in older browsers currently still relatively widely in use, so it should currently merely be used for progressive enhancement.

Your best bet is to just define an error page which deals with the case when the enduser invokes an action while the session is expired. See also javax.faces.application.ViewExpiredException: View could not be restored.

于 2013-03-22T15:01:53.087 に答える
0

HttpSessionListerner では、User に応答を送信できません。これを実現する 1 つの良い方法は、ポーリングを使用することです。ブラウザは定期的に HTTP リクエストを送信し、すぐに応答を受け取ります。
これを行うには多くの方法があります。

  1. プレーンな古い JavaScript を使用してポーリングできます。これは、クロス ブラウザー環境で機能します。

    関数リフレッシュ() {

    // make Ajax call here, inside the callback call:
    
    setTimeout(refresh, 5000);
    
    // ...
    

    }

    // initial call, or just call refresh directly
    

    setTimeout(更新、5000);

  2. Web ソケットを使用できます。Web ソケットの仕様は、以下のリンクにあります。

    http://dev.w3.org/html5/websockets/

于 2013-08-06T05:20:26.103 に答える
-1

Filter を使用して、次のテストを実行できます。

HttpSession session = request.getSession(false);
if(session != null && !session.isNew()) {
    chain.doFilter(request, response);
}
 else {enter code here
    response.sendRedirect("/login.jsp");
 }
于 2015-08-14T06:52:05.077 に答える