2013-03-22 13 views
10

このトピックに関する多くの記事を見てきましたが、私の場合にはうまくいくソリューションを手に入れることができませんでした。HttpSessionタイムアウト後のリダイレクト

私は私が持っている私のweb.xmlではJSF 2.0を使用してJava EE 6(7.1はJBoss AS上で展開)

を使用しています:

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

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

アプローチ1:私は

<filter-mapping> 
    <filter-name>TimeOutFilter</filter-name> 
    <url-pattern>*.xhtml</url-pattern> 
</filter-mapping> 
を試してみましたweb.xml

@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() { 
    } 
} 

:私は次のフィルタを試してみましたフィルター

を使用して、私が試してみました何

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

フィルターは、すべての要求(コンソールで「フィラー」と呼ばれる)のログとして呼び出されるため、機能します。 ただし、セッションがタイムアウトすると呼び出されません。

アプローチ2:HttpSessionLister

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

public void sessionDestroyed(HttpSessionEvent se) { 
} 

特定のページにリダイレクトできませんでした。ユーザーをリダイレクトする場合は、通常、のNavigationHandlerを使用しますが、この場合はFacesContextFacesContext.getCurrentInstance()が返されます。null)はありません。

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

質問

この問題を解決するために行くための最善の方法は何ですか?上記の2つのアプローチのいずれかを機能させるために私は何ができますか?

+1

関連:http://stackoverflow.com/q/をウェブソケット仕様は、リンクの下に存在し、 4992526/1065197 –

+0

@ LuigiMendoza:面白いおかげです。私は 'ViewExpiredException'を見たことがありませんが、可能であれば、ユーザが何もクリックすることなくログインページにリダイレクトしたいと思います。 – phoenix7360

+0

サーバー側で302をトリガーするには、クライアント側で何らかのポーリング形式が必要です。ハートビート... –

答えて

15

クライアントがHTTP要求を送信していない限り、HTTP応答を送信することはできません。そのような単純な。それがHTTPの仕組みです。そうでなければ、ウェブサイトが、リクエストされていないクライアントがHTTPレスポンスをアンタスキープッシュすることができれば、インターネットは非常に異なって見えてしまいます。

AのJavaScriptベースのハートビートが答えとしてhereのように、クライアントのキーボード/マウスの活動に基づいて、あるいはきたあなたは基本的に単一ページのWebアプリケーションが(したがって、あなたが効果的にならhereに答えようのようなメタrefreshヘッダが解決策になりますセッションスコープではなくビュースコープを使用します)。ただし、同じセッション内の複数のタブ/ウィンドウでページを開いているとうまく動作しません。

Websocketsは理論上、何かをクライアントにプッシュする正しいソリューションですが、これはアクティブなセッションを必要とします。鶏卵問題また、比較的広く使用されている古いブラウザでは機能しないため、現在は漸進的な拡張にのみ使用する必要があります。

セッションが終了したときにエンドユーザーがアクションを呼び出す場合のエラーページを定義することをお勧めします。 javax.faces.application.ViewExpiredException: View could not be restoredも参照してください。

+1

私は今私の誤解を参照してください。自動的にユーザーをリダイレクトするのではなく、セッションがタイムアウトした後でアクションを実行するかどうかをユーザーに知らせる必要があります。 – phoenix7360

-1

java-EE6とJSFを使用していますが、JSPコードを使用したり、以下のコードをサーブレットで使用することができます。 web.xmlファイルでsession-timeoutを設定した後で、ユーザ名を使用してセッションを確認していると仮定します。JSPコードとサーブレットコードは似ています。 セッションの検証コードは次のようになります(JSP形式) ユーザー名がデータベースのプライマリキーとして機能する場合。

<% 
    String un = (String)session.getAttribute("un"); 

    if(un == null){ 
    response.sendRedirect(login page); 
    return; 
}else{ 
     code to process login form 
} 
    %> 

サーブレットコードを使用すると、ユーザーへの応答を送信することはできませんHttpSessionListernerではこの

String un = (String)session.getAttribute("un"); 
if(un == null){ 
    response.sendRedirect(loginPage); 
} 
0

ようになります。これを実現する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ソケットを使用できます。フィルタを使用して、次の試験を行うことができ

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

-1

HttpSession session = request.getSession(false); 
if(session != null && !session.isNew()) { 
    chain.doFilter(request, response); 
} 
else {enter code here 
    response.sendRedirect("/login.jsp"); 
} 
関連する問題