WebアプリケーションはJBoss7.1.1およびJava(JPA2およびRichFaces4)で実行されます。現時点での問題は、ユーザーがログインしているとアプリケーションがスタックするだけで、しばらくの間アプリケーション内で何もしないことです(おそらくセッションのタイムアウトが原因です)。次に、ユーザーはWebアプリケーションを再度ロードする必要がありますが、これはあまり専門的ではありません。
上記のテクノロジーを使用して自動ログアウトを実装する方法について、ヒントを教えてください。
[更新]
私は多くの可能性を試しましたが、どれも正しく機能しません。私の考えは、セッションがいつ期限切れになるかを知っているSessionTimeoutListenerを実装することです。
@Logged
@WebListener
@Named
public class SessionTimeoutListener implements HttpSessionListener
{
@Inject
private Logger logger;
@Override
public void sessionCreated(HttpSessionEvent event)
{
// not used.
}
@Override
public void sessionDestroyed(HttpSessionEvent event)
{
logger.info("Session destroyed.");
ApplicationContext.setAutoLoggedOut(true);
}
}
これは機能します。しかし、その後、すべての問題が発生します。FacesContextがnullであるため、リダイレクトできません。NameNotFoundExceptionなどの例外が発生するため、プッシュイベントを発生させることができません(多くのことを試しましたが、イベントの発生はこれでも機能しないようです)。次に、ApplicationContext.isAutoLoggedOut()でa4j:pollを試しましたが、ポーリングイベントを実行するとセッションが期限切れにならないため、これも機能しません。私はいつも行き止まりになります。SessionTimeoutListenerからなんらかの方法でリダイレクトできれば、これが解決策になります。
[考えられる解決策]
セッションの有効期限が切れた後、ビュー内のいずれかのボタンをクリックすると実行されるログアウトに満足しました。この現在のソリューションは基本的なものであり、まだ本番環境には適用できませんが、このソリューションは機能し、それを基に構築します。上位のSessionTimeoutListenerを使用します。さらに、SessionTimeoutListenerの後に呼び出されるPhaseListenerを使用しているため、セッションが期限切れになると、SessionTimeoutListenerが呼び出されてセッションが破棄されますが、SessionTimeoutPhaseListenerにはまだFacesContextがあります。そこで、そこからログアウトページにリダイレクトできます。
public class SessionTimeoutPhaseListener implements PhaseListener
{
private static final long serialVersionUID = -8603272654541248512L;
@Override
public void beforePhase(PhaseEvent event)
{
//not used.
}
@Override
public void afterPhase(PhaseEvent event)
{
FacesContext facesContext = event.getFacesContext();
if (ApplicationContext.isAutoLoggedOut())
{
ApplicationContext.setAutoLoggedOut(false);
try
{
facesContext.getExternalContext().redirect("./logout.xhtml");
}
catch (IOException e)
{
}
}
}
@Override
public PhaseId getPhaseId()
{
return PhaseId.RESTORE_VIEW;
}
}
ApplicationContextは、ブール変数を格納する@ApplicationScopedを持つクラスですが、現在アプリケーションを使用しているすべてのユーザーに影響するため、これを変更する必要があります。それを解決するために、いくつかの「スレッドローカルコンテキスト」について考えます。自動ログアウトと手動ログアウトを区別する必要があります。どちらの場合も、リスナーが呼び出されます。このソリューションは現時点では機能しますが、「autoLoggedOut」をfalseに設定しないと、JSFによって何度も呼び出されるため(ブラウザーでリダイレクトループエラーが発生します)、PhaseListenerでのリダイレクトも注意が必要です。 ..私が言ったように、基本的なことだけですが、PhaseListenerを使用することがおそらく唯一の適切な解決策です。