正在提交响应,并且 doFilter 链已损坏

Bre*_*olt 5 java redirect servlets servlet-filters

为了这就是我需要发生的事情:

请求于blah.com/test

  1. ServletFilter A - 创建配置文件,然后调用chain.doFilter
  2. ServletFilter B(由于 url 模式不匹配而被跳过)
  3. Servlet - 更改配置文件,repsonse.setStatus&response.addHeader("Location", target)
  4. ServletFilter A - 应该根据配置文件创建一个 cookie

实际发生了什么:

  1. ServletFilter A - 创建配置文件,然后调用chain.doFilter
  2. ServletFilter B(由于 url 模式不匹配而被跳过)
  3. Servlet - 更改配置文件,repsonse.setStatus&response.addHeader("Location", target)
  4. 重定向已提交,ServletFilter A 未完成任务

我认为这可能与您可以在 ServletFilter 配置中设置的调度程序值有关。

有任何想法吗?

Ram*_*PVK 5

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

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

}
}
Run Code Online (Sandbox Code Playgroud)