簡単な質問です。ログインページを含む JSF アプリケーションがあります。問題は、ユーザーがログイン ページをロードし、しばらくそのままにしてからログインしようとすると、セッションが期限切れになり、ViewExpiredException がスローされることです。これが発生したときにログインにリダイレクトすることはできますが、それはあまりスムーズではありません。追加の試行なしで、このフローが適切にログインできるようにするにはどうすればよいですか?
4 に答える
アップデート
<f:view>
Mojarra 2.1.19 / 2.2.0 の時点で、一時属性を trueに設定できるようになりました。
<f:view transient="true">
Your regular content
</f:view>
こちらのBaluscの ブログで読むことができます:
http://balusc.blogspot.com.br/2013/02/stateless-jsf.html
オリジナル
Facelets を使用している場合は、独自の ViewHandler を作成してこれを処理できます。
public class LoginViewHandler extends FaceletViewHandler
{
public LoginViewHandler( ViewHandler viewHandler )
{
super( viewHandler );
}
@Override
public UIViewRoot restoreView( FacesContext ctx, String viewId )
{
UIViewRoot viewRoot = super.restoreView( ctx, viewId );
if ( viewRoot == null && viewId.equals( "/login.xhtml" ) )
{
// Work around Facelet issue
initialize( ctx );
viewRoot = super.createView( ctx, viewId );
ctx.setViewRoot( viewRoot );
try
{
buildView( ctx, viewRoot );
}
catch ( IOException e )
{
log.log( Level.SEVERE, "Error building view", e );
}
}
return viewRoot;
}
}
「/login.xhtml」をログイン ページに変更します。これにより、ビューを復元できるかどうかが確認されます。復元できない場合、現在のビューがログイン ページである場合は、ビューが作成および構築されます。
これを face-config.xml で次のように設定します。
<application>
<!-- snip -->
<view-handler>my.package.LoginViewHandler</view-handler>
</application>
Facelets (つまり JSP) なしで JSF を使用している場合は、クラスで ViewHandlerWrapper を拡張してみてください。buildView() は使用できないことに注意してください。createView() だけでビューが正しく設定されることを願っていますが、JSF/JSP については 100% 確信が持てません。
ログイン ページがセッション スコープ内にあるように思えますが、実際にはそうする必要はありません。リクエスト スコープは、ログイン ページに対して適切である必要があります (現実的には、ユーザーがログインする前にセッションに何も存在しないため)。ユーザーがログインすると、この問題が再び発生する可能性がありますが、Phill のアイデアはそれ以降非常に優れています。
jsp を使用すると、このディレクティブを含むページのセッションを無効にすることができます<%@ page session="false" %>
。jsf にも似たようなものがあるはずです。
少しハッキーなソリューションのカップル:
- (非常にハッキー)
<meta http-equiv="refresh" content="5"/>
タグを使用して、ページを頻繁に自動的にリロードします。 - JavaScript関数を使用して、定期的に「ping」要求をサーバーに送信し、セッションを存続させます。
職場ではIceFacesを使用しており、セッションの有効期限が切れたことを自動的に検出し、事実を警告するポップアップを表示します。ただし、何らかの理由でログインページで問題が発生することがあります。