有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java响应正在提交,doFilter链已断开

为了做到这一点,我需要:

关于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配置中设置的dispatcher值有关

有什么想法吗


共 (2) 个答案

  1. # 1 楼答案

    我认为,当响应到达ServletFilter AStep 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();
        }
    
    }
    }
    
  2. # 2 楼答案

    它很好用。无论如何,需要注意的是,为了防止缓冲响应大小小于8KB,除非在调用getWrapperBytes()之前刷新响应,否则它将无法工作

    这是由于ServletAPI的内部实现