7

ロジックは、フィルタがヒットし、条件が true ではないため、フィルタ チェーンを通過するというものです。応答がコミットされた後、フィルターがヒットし、条件が真になります (要求属性が設定されました)。転送を実行するために入りますが、ページは転送されません。初めてチェーンにヒットする前に転送するさまざまなロジックをテストし、正常に転送されたため、これはコミットされている応答と関係があることを知っています。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

    HttpServletRequest httpServletRequest = (HttpServletRequest)request;

    if (some condition equals true) {
        httpServletRequest.getRequestDispatcher("/home.jsp").forward(request, response);
        return;
    } else {
        chain.doFilter(request, response);
    }
}

私のデプロイメント記述子の例:

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.filters.MyFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
    <dispatcher>REQUEST</dispatcher>  
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping>
4

2 に答える 2

16

の「コミット済み」ステータスは、HttpServletResponse実際には、応答ヘッダーが基になるソケットに書き込まれたかどうかを示す方法です。「コミットされた」応答には、(少なくとも) 最初の行が書き込まれています。応答の最初の行にはステータス コードが含まれているため、コミットされた応答のステータス コードを変更することはできません。つまり、ステータスを 3xx に変更してリダイレクトするには遅すぎるということです。同様に、すでに応答の送信を開始しているため、ローカル転送を行うことはできません。

于 2010-08-04T15:48:54.407 に答える
5

カスタムHttpServletResponseを使用して、目的を達成できます。このラップされた HttpServletResponse をフィルター チェーンに渡します。すべての書き込みリクエストを格納するローカル OutputStream 、ステータス コードとヘッダーを格納するためのローカル変数を提供できます。フィルターに戻ったら、リダイレクトを実行するか、ローカル変数の結果をラッパーから元の ServletResponse にコピーするかを決定できます (つまり、ステータス コードとヘッダーを設定し、結果をローカル出力ストリームからサーブレット応答の出力ストリーム)。

編集:

を使用するコード例については、 「カスタマイズされた要求と応答のプログラミング」セクションを参照してくださいCharResponseWrapper。この例ではカスタム Writer を使用していますが、OutputStream に簡単に拡張できます。サーブレットの使用方法に基づいて、いずれかまたは両方をオーバーライドし、元の応答へのコミットを遅らせる必要がありgetWriter()ますgetOutputStream()。さらに、フィルタ チェーンの下流でいつでも forward を実行できるように、isCommitted()returnをオーバーライドする必要があります。また、リダイレクト/転送後に新しいコンテンツ (ヘッダーを含む) を保存するために、新しい/を初期化するfalseためにオーバーライドする必要があります。resetBuffer()OutputStreamWriter

于 2011-12-14T02:48:12.813 に答える