Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

java - Response is committing and doFilter chain is broken

In order this is what I need to happen:

Request on blah.com/test

  1. ServletFilter A - creates profile, then calls chain.doFilter
  2. ServletFilter B (is skipped because url pattern doesn't match)
  3. Servlet - alters the profile, repsonse.setStatus & response.addHeader("Location", target)
  4. ServletFilter A - should create a cookie based on the profile

What is actually happening:

  1. ServletFilter A - creates profile, then calls chain.doFilter
  2. ServletFilter B (is skipped because url pattern doesn't match)
  3. Servlet - alters the profile, repsonse.setStatus & response.addHeader("Location", target)
  4. Redirect is committed and ServletFilter A does not complete tasks

I think this may be related to the dispatcher values that you can set in the ServletFilter configs.

Any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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();
    }

}
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...