响应正在提交,doFilter链断开

时间:2012-06-14 01:37:44

标签: java servlets redirect servlet-filters

这是我需要发生的事情:

请求blah.com/test

  1. ServletFilter A - 创建个人资料,然后调用chain.doFilter
  2. ServletFilter B(由于网址格式不匹配而被跳过)
  3. Servlet - 更改个人资料repsonse.setStatus& response.addHeader("Location", target)
  4. ServletFilter A - 应根据个人资料
  5. 创建一个cookie

    实际发生了什么:

    1. ServletFilter A - 创建个人资料,然后调用chain.doFilter
    2. ServletFilter B(由于网址格式不匹配而被跳过)
    3. Servlet - 更改个人资料repsonse.setStatus& response.addHeader("Location", target)
    4. 提交重定向,ServletFilter A无法完成任务
    5. 我认为这可能与您在ServletFilter配置中设置的调度程序值有关。

      有什么想法吗?

2 个答案:

答案 0 :(得分:3)

我认为响应在ServletFilter A达到Step 4时就会提交。一旦响应被提交,即标题被写入客户端,您就无法进行需要添加标题的操作。添加cookie等操作。

如果您希望在Step 4尝试换行HttpServletResponse之前不提交响应,并返回缓冲数据的自定义输出流,直到达到step 4,然后提交响应。< / p>

以下是示例代码:

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

}
}

答案 1 :(得分:1)

工作正常。无论如何,重要的是要注意,如果缓冲的响应大小小于8KB,除非在调用getWrapperBytes()之前刷新响应,否则它将无法工作。

这是由于servlet-api内部实现。