本文介绍了响应正在提交并且 doFilter 链已损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In order this is what I need to happen:

请求在 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 配置中设置的调度程序值有关.

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

有什么想法吗?

推荐答案

我认为响应在 Step 4 到达 ServletFilter A 时正在提交.一旦响应被提交,即标头被写入客户端,您就不能进行需要添加标头的操作.添加cookie之类的操作.

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.

如果您希望在 Step 4 之前不提交响应,请尝试包装 HttpServletResponse 并返回您的自定义输出流,该流缓冲数据直到它到达 step 4 然后提交响应.

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.

这是示例代码:

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

}
}

这篇关于响应正在提交并且 doFilter 链已损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-25 10:44