Response is committing and doFilter chain is broken

前端 未结 2 1180
孤街浪徒
孤街浪徒 2020-12-10 21:31

In order this is what I need to happen:

Request on blah.com/test

  1. ServletFilter A - creates profile, then calls chain.doFilter
相关标签:
2条回答
  • 2020-12-10 22:00

    It works fine. Anyway it's important to note that, just in case the buffered response size is smaller than 8KB, it won't work unless you flush the response before u call getWrapperBytes().

    This is due to servlet-api internal implementation.

    0 讨论(0)
  • 2020-12-10 22:03

    I think the response is getting committed when it reaches ServletFilter A at Step 4. Once the response is committed, i.e, headers are written to the client, you cannot do operations which requires adding headers. The operations like adding cookies.

    If you want the response not to be committed till Step 4 try wrapping HttpServletResponse and returning your custom output stream which buffers the data till it reaches step 4 and then commits the response.

    Here is the sample code :

    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();
        }
    
    }
    }
    
    0 讨论(0)
提交回复
热议问题