3

これが私が起こる必要があるものです:

リクエストblah.com/test

  1. ServletFilter A - プロファイルを作成してから呼び出すchain.doFilter
  2. ServletFilter B (URL パターンが一致しないためスキップされます)
  3. サーブレット - プロファイルを変更するrepsonse.setStatus&response.addHeader("Location", target)
  4. ServletFilter A - プロファイルに基づいて Cookie を作成する必要があります

実際に起こっていること:

  1. ServletFilter A - プロファイルを作成してから呼び出すchain.doFilter
  2. ServletFilter B (URL パターンが一致しないためスキップされます)
  3. サーブレット - プロファイルを変更するrepsonse.setStatus&response.addHeader("Location", target)
  4. リダイレクトがコミットされ、ServletFilter A がタスクを完了しない

これは、ServletFilter 構成で設定できるディスパッチャーの値に関連している可能性があると思います。

何か案は?

4

2 に答える 2

4

ServletFilter Aに到達すると、応答がコミットされていると思いますStep 4。応答がコミットされると、つまりヘッダーがクライアントに書き込まれると、ヘッダーの追加が必要な操作を実行できなくなります。クッキーの追加などの操作。

レスポンスをコミットしないようにする場合は、カスタム出力ストリームをStep 4ラップHttpServletResponseして返してみてください。これにより、データが到達するまでバッファリングされてからstep 4、レスポンスがコミットされます。

サンプルコードは次のとおりです。

public class ResponseBufferFilter implements Filter
{
public void init(FilterConfig filterConfig) throws ServletException
{
}

public void doFilter(ServletRequest request, ServletResponse response, 
   FilterChain filterChain) throws IOException, ServletException
{
    HttpServletResponse httpResponse = (HttpServletResponse)response;
    BufferResponseWrapper wrapper = new BufferResponseWrapper(httpResponse);
    filterChain.doFilter(request, resposneWrapper);
    response.getOutputStream().write(wrapper .getWrapperBytes());
}

public void destroy()
{
}

private final class BufferResponseWrapper extends HttpServletResponseWrapper
{

    MyServletOutputStream stream = new MyServletOutputStream();

    public BufferResponseWrapper(HttpServletResponse httpServletResponse)
    {
        super(httpServletResponse);
    }

    public ServletOutputStream getOutputStream() throws IOException
    {
        return stream;
    }

    public PrintWriter getWriter() throws IOException
    {
        return new PrintWriter(stream);
    }

    public byte[] getWrapperBytes()
    {
        return stream.getBytes();
    }
}

private final class MyServletOutputStream extends ServletOutputStream
{
    private ByteArrayOutputStream out = new ByteArrayOutputStream();

    public void write(int b) throws IOException
    {
        out.write(b);
    }

    public byte[] getBytes()
    {
        return out.toByteArray();
    }

}
}
于 2012-06-14T05:31:50.773 に答える
1

それは正常に動作します。とにかく、バッファーされた応答のサイズが 8KB より小さい場合に備えて、 u を呼び出す前に応答をフラッシュしない限り機能しないことに注意することが重要ですgetWrapperBytes()

これは、servlet-api の内部実装によるものです。

于 2012-08-16T14:19:03.920 に答える