9

HttpServletResponseコンテンツ (通常は HTML) がレンダリングされた後に Cookie を に追加したいと思います。

ここ ( http://osdir.com/ml/java.jasig.uportal/2005-10/msg00276.html ) とここ (ヘッダーがフラッシュされた後、Java の応答にクッキーを追加しますか? ) で述べたように、これは応答をバッファリングして、フラッシュされてクライアントに送信されないようにすることで可能です (ヘッダーがクライアントに送信された後、応答がコミットされ、それ以上のヘッダー、つまり Cookie ヘッダーをクライアントに送信できないため)。

これが当面の目標であると仮定すると、これを達成するための可能な方法は を使用することであるHttpServletResponseWrapperことがわかります。そのメソッドをオーバーライドしてflushBuffer()、ヘッダー\コンテンツがクライアントに実際にフラッシュされるのを防ぐことができます。

public class BufferedHttpServletResponse extends HttpServletResponseWrapper {

    public BufferedHttpServletResponse(HttpServletResponse response) {
        super(response);
    }

    public void flushBuffer() {
    }

}

Filterそして、フィルタ チェーンの残りの部分で使用するために、このバッファリングされた応答を に適用します。

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    BufferedHttpServletResponse bufferedResponse = new BufferedHttpServletResponse(response);

    chain.doFilter(request, bufferedResponse);

    // ... create Cookie and add it to response ... response.addCookie(newCookie)
    // response.flushBuffer() ?        

}

質問: 上記は大丈夫ですか、それとも完全にオフですか? 応答のバッファは、終了後までコンテンツ\ヘッダーでいっぱいになり(おそらくサイズが変更され)doFilter()、他のフィルタまたはサーブレットコンテナ(Tomcat)によってフラッシュされてクライアントに送信されますか?自分で応答をフラッシュする必要がありますか? ... ここで言及されています ( HttpServletResponse.getOutputStream()/.getWriter() で .close() を呼び出す必要がありますか? ) そのストリームを閉じるべきではありませんが、この場合、応答をフラッシュする必要がありますか?

必ずしもこれが当面の目標であるとは限りません:私の一般的な問題は、クライアント ブラウザーに Cookie を設定する必要があることですが、Cookie の値は、応答のコンテンツのレンダリング中に発生するもの (Struts 1.0 で発生するもの) に依存します。アクション、その後は Velocity テンプレートで) - 設定する Cookie の値は、(サーブレット -> HTML のレンダリング) フロー全体を通過した後にのみわかります。

教えてください。ありがとう。

4

1 に答える 1

-2

誰もこれを受け入れる準備ができていないようです。少なくとも私の視点を提供しようと思います。

質問に入る前に、まず、サーブレット フィルターの主なタスクを見てみましょう。

  • 要求を照会し、それに応じて行動します。
  • リクエストとレスポンスのペアがそれ以上通過しないようにブロックします。
  • リクエスト ヘッダーとデータを変更します。これを行うには、リクエストのカスタマイズされたバージョンを提供します。
  • 応答ヘッダーとデータを変更します。これを行うには、応答のカスタマイズされたバージョンを提供します。

ソース: http://docs.oracle.com/javaee/6/tutorial/doc/bnagb.html

質問に戻って、応答別名をカスタマイズすることで、応答ヘッダーを変更できますResponseWrapper

コードを見ると、カスタム レスポンスを変更するのではなく、元のレスポンスを変更しようとしていますが、これは (元のレスポンスに Cookie を追加することは) OK ではありません

したがって、それを行う適切な方法は、以下のサンプルのようなカスタムに Cookie を追加することです。

   private class CustomResponseWrapper extends HttpServletResponseWrapper {

        private Collection<Cookie> myCookies = new ArrayList<Cookie>();

        public CustomResponseWrapper(HttpServletResponse response) {
            super(response);
        }

        @Override
        public void addCookie(Cookie cookie) {
            super.addCookie(cookie);
            myCookies.add(cookie);
        }
    }
于 2012-08-31T21:15:30.223 に答える