【问题标题】:Updating response after doFilterdoFilter 后更新响应
【发布时间】:2012-09-23 01:03:53
【问题描述】:

我希望在 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");
    }                                       
}

还是不行。我是不是做错了什么?

【问题讨论】:

  • 为什么要在doFilter()之后做?
  • 我想添加性能数据,这似乎是正确的选择。
  • 我在添加性能信息时遇到了类似的问题。它可能取决于容器何时提交响应,您可能无法控制它。我最终所做的是将 html 注释中的信息(这是我生成的 html)添加到响应的正文中。此外,性能信息仅在请求中包含某些参数时才会生成。
  • @IdoBarash 你得到答案了吗?如果可以,可以贴在这里吗?
  • 你可以参考这个答案-stackoverflow.com/questions/32829124/…

标签: java servlets


【解决方案1】:

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

似乎 doFilter 刷新了响应。

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

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

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

【讨论】:

  • 谢谢,试过了,还是不行。我更新了问题的正文。
  • 只有在调用 flush 方法时才提交响应。此外,当缓冲区已满时,响应将自动提交。考虑覆盖 getOutputStream() 和 getWriter() 方法
【解决方案2】:

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

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

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

希望对你有帮助。

【讨论】:

  • 我需要根据内容类型设置响应头。有什么想法吗?
  • @Arjun,你可以在设置了 content-type 之后直接设置 headers(content-type 也是一个 header,所以如果你能设置它,你也可以设置其他 headers)
  • 我只想在内容类型为“text/html”时设置响应头。我没有在我的代码中设置内容类型。我正在设置缓存控制。
  • 伙计们检查stackoverflow.com/a/20555802/3884173 通过在任何地方获取响应对象来设置标头(即使在 POJO 中!)
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2014-07-30
    • 2019-09-21
    • 2010-09-07
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    相关资源
    最近更新 更多