1

私は omnifaces FullAjaxExceptionHandler を使用して、例外が ajax リクエストで発生したときにリダイレクトします。私の場合は、ViewExpiredException をキャッチします。

私は私のケースを説明しようとします:

1) セッションを無効にして、この "/login?faces-redirect=true" のようなアクションを返すための commandButton (ajax リクエスト) を含む index.xhtml ページがあります。

2) 同じブラウザで index.xhtml を 2 回開きます。

3) 最初の index.xhtml でボタンをクリックします (セッションは無効になり、login.xhtml にリダイレクトされます)。

この時点で、ユーザーが正常にログに記録されているかどうかを確認するカスタム PhaseListener があることを考慮に入れます。login.xhtml はパブリック アクセス用ですが、index.xhtml は許可されたユーザーに制限されています。

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/index.xhtml</location>
</error-page>
<error-page>
    <error-code>403</error-code>
    <location>/403.xhtml</location>
</error-page>

4) 2 番目の index.xhtml に移動し (この時点でセッションは無効になります)、ボタンをクリックして例外を起動します。

FullAjaxExceptionHandler は ViewExpiredException をキャッチし、index.xhtml をレンダリングしようとしますが、セッションが無効化されたように、フェーズ リスナーがユーザーが承認されているかどうかを確認しているのと同時に、ユーザーは承認されておらず、フェーズ リスナーが responseSendError(403) を起動しますが、そうではありませんajax リクエストであるため、403.xhtml が表示されます。

PhaseListener から 403.xhtml を表示するために 403 エラーを送信するにはどうすればよいですか? responseSendError は、FullAjaxExceptionHandler の通常のプロセスをキャンセルしています。その例外が発生した瞬間、リダイレクトは行われません。

さらに、ビューの有効期限が切れる時期を明確にするために、index.xhtml にリダイレクトする必要があります。これは、本番環境では CAS (Central Authentication Service) を使用しているためです。

4

1 に答える 1

1

具体的な問題は、本質的にはとは無関係FullAjaxExceptionHandlerです。それを使用しない場合でも、まったく同じ問題が発生します。responseSendError()少なくとも2つの理由により、ajaxリクエストで使用することはできません。

  1. ajax応答を正常に処理するには、ステータスが200である必要があります。
  2. ajax応答は、プレーンなHTMLページではなく、有効なJSFajaxXML構造を表す必要があります。

の中でPhaseListener、あなたの最善の策はを使用することExternalContext#redirect()です。

ExternalContext ec = context.getExternalContext();

if (context.getPartialViewContext().isAjaxRequest()) {
    ec.redirect(ec.getRequestContextPath() + "/403.xhtml");
} else {
    ec.responseSendError(403, "Unauthorized");
}

確かに、これは最終的にHTTP 200応答になりますが、これまでのところ、ajaxリクエストの場合にエラーページ全体を表示したい場合に取得できる最善の方法です。


具体的な問題とは関係なく、aViewExpiredExceptionがスローされた場合、ほとんどの場合、原因はセッションの期限切れです。/login.xhtml例外のエラーページが。の代わりに直接指すようにする方が理にかなっています/index.xhtml。または、少なくともよりユーザーフレンドリーな、エンドユーザー/expired.xhtmlがそこにたどり着いた理由と彼のオプションが何であるかについての説明といくつかのリンクが含まれているページへ。

于 2013-02-20T11:40:18.677 に答える