5

web.xml で次のように定義しています。

<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/shared/errors/DefaultErrorPage.xhtml</location>
</error-page>
<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/shared/errors/ViewExpired.xhtml</location>
</error-page>

また、faces-config.xml で Omnifaces の FullAjaxExceptionHandler を使用しています。

<factory>
    <exception-handler-factory>
        org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory
    </exception-handler-factory>
</factory>

FullAjaxExceptionHandler は ajax 呼び出しに対して正常に動作していますが、ページを直接ヒットしてエラーが発生すると、移動しようとしていたページのレンダリングが開始されますが、終了せず、Web で定義されたエラー ページが表示されます。 xml がレンダリングされ、部分的にレンダリングされたページの後にエラー ページが埋め込まれます。

(私は Mojarra JSF 2.1.3 を含む Glassfish 3.1.1 を使用しています) 編集: 現在、Glassfish 3.1.2.2 および JSF 2.1.11 を使用しています

編集: 次のことを発見しました: エラーが発生しているページはテンプレートを使用しています ( <ui:composition template="/shared/shared/commonLayout.xhtml">) ページがテンプレートを使用しないように変更し、テンプレートからすべてのコードを追加するだけで、正常に動作します。

4

1 に答える 1

5

これは、例外がスローされる前に応答がすでにコミットされている場合に発生します。JSF の奥深くで何らかの方法で明示的に呼び出された場合、応答はコミットServletOutputStream#flush()されます。これは、多くの場合、応答バッファー (通常、ほとんどのコンテナーではデフォルトで 2KB) がオーバーフローした場合にのみ発生します。コミットされた応答は、後戻りできないポイントです。サーバーは、送信済みのバイトをクライアントから戻すことはできません。サーバーには基本的に 2 つのオプションがあります。

  • 応答をそのままにして、例外をサーバー ログにのみ記録します。
  • とにかく、エラーページを応答に書き込んでみてください。

Glassfish のセットアップでは、明らかに 2 番目の方法が選択されています。それらのどれも完璧ではありません。クライアントはまだ中途半端な HTML 応答で終わることになり、最終的にエンドユーザーにどのように見えるかは、Web ブラウザーがこれまでに取得した HTML を解釈して表示する際に最善を尽くす方法に依存します。

ただし、JSF 開発者は、いくつかの方法を使用してこれを回避できます。そもそも、応答のレンダリング中にその例外がスローされたのはなぜですか? それは実際にあなた自身のコードのバグを示していませんか? 応答をレンダリングする前に、例外に敏感なビジネス ジョブを実行したほうがよいのではないでしょうか? これには、とりわけ使用できます<f:event type="preRenderView">

<f:event type="preRenderView" listener="#{bean.init}" />

なんらかの理由でそれが実際に不可能な場合は、例外が発生する前に応答が自動フラッシュされないように、応答バッファーのサイズを最大の HTML 応答のサイズよりも大きくすることを検討できます。これは、すべての HTML 応答が 100KB の制限内に収まると想定する次のコンテキスト パラメーターによって実行できます。

<context-param>
    <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
    <param-value>102400</param-value><!-- 100KB -->
</context-param>
于 2012-08-02T19:36:03.543 に答える