在doFilter之后更新响应

时间:2012-10-02 07:07:14

标签: java servlets

我希望在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答案后,我决定尝试使用Response包装器:


这是包装器:

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

仍然无效。我做错了吗?

3 个答案:

答案 0 :(得分:3)

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

doFilter不会刷新响应,但执行请求时可能会导致很多事情。 (显式调用response.flush(),响应中的主体太大),而你无法控制它。

但是,您可以使用HttpServletResponseWrapper来更改此内容。

希望它有所帮助。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

在您发布的代码中,您不能说:

  

似乎doFilter刷新了响应。

有一些关于提交回复的规则。

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

如果要避免此行为,则应使用请求/响应包装器,这将阻止应用过滤器的组件提交响应。