2

我希望在doFilter()函数完成运行后添加一个 HTTP 标头。

public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {
  HttpServletResponse httpResp = (HttpServletResponse) response;

  try {
    chain.doFilter(request, httpResp);

  } finally {           
    httpResp.setHeader("ADD A HEADER: ", "HEADER");
  }                                     
}

似乎doFilter刷新了响应。


更新:

谢谢。查看 IgorMadjeric 和richardtz 的答案后,我决定尝试响应包装器:


这是包装器:

public class BufferedHttpServletResponse extends HttpServletResponseWrapper {

public BufferedHttpServletResponse(HttpServletResponse response) {
    super(response);
}

public void flushBuffer() {
    System.out.println("flush");
}

}

这是修改后的代码:

public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {
    HttpServletResponse httpResp = (HttpServletResponse) response;

    try {
        BufferedHttpServletResponse bufferedResponse = new BufferedHttpServletResponse(httpResp);
        chain.doFilter(request, bufferedResponse);

    } finally {         
        bufferedResponse.setHeader("ADD A HEADER: ", "HEADER");
    }                                       
}

仍然无法正常工作。我做错什么了吗?

4

3 回答 3

3

一旦刷新/提交(它已经发送到客户端),您就无法修改标头的响应。

doFilter 不会刷新响应,但是请求执行中的许多事情都可能导致它。(对 response.flush() 的显式调用,响应中的正文太大),并且您无法控制它。

但是,您可以使用 HttpServletResponseWrapper 来更改它。

希望能帮助到你。

于 2012-10-02T07:32:47.483 回答
1

正如评论和这个问题中已经提到的那样,覆盖flushBuffer()可能还不够,但您还需要覆盖getWriter()和getOutputStream()。在某些情况下,即使这样可能还不够。例如,如果在响应上调用 sendError(int),它也可以被提交。

于 2015-09-23T21:08:37.657 回答
0

就您发布的代码而言,您不能说:

似乎 doFilter 刷新了响应。

关于提交响应有一些规则。

过滤后,某些组件可能已经提交了响应。

如果您想避免这种行为,您应该使用请求/响应包装器,这将阻止组件,您的过滤器应用于提交响应。

于 2012-10-02T07:30:17.537 回答