9

我想HttpServletResponse在其内容(通常是 HTML)被渲染后添加一个 cookie。

正如这里(http://osdir.com/ml/java.jasig.uportal/2005-10/msg00276.html)和这里(在标头被刷新后将cookie添加到Java中的响应中?),这个通过缓冲响应是可能的,因此它不会被刷新并发送到客户端(因为在将标头发送到客户端之后,响应已提交,并且不再有标头,即 cookie 标头,可以发送到客户端)。

假设这是手头的目标:我认为实现此目的的一种可能方法是使用HttpServletResponseWrapper,我可以覆盖其flushBuffer()方法并防止将 headers\content 实际刷新到客户端:

public class BufferedHttpServletResponse extends HttpServletResponseWrapper {

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

    public void flushBuffer() {
    }

}

并在 a 中应用此缓冲响应,以Filter供过滤器链的其余部分使用:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    BufferedHttpServletResponse bufferedResponse = new BufferedHttpServletResponse(response);

    chain.doFilter(request, bufferedResponse);

    // ... create Cookie and add it to response ... response.addCookie(newCookie)
    // response.flushBuffer() ?        

}

问题:以上是可以的,还是完全关闭了?响应的缓冲区是否会一直充满内容\标题(并且可能会重新调整大小),直到我doFilter()退出之后,然后被其他过滤器或 servlet 容器(Tomcat)刷新并发送到客户端?我应该自己刷新响应吗?...这里提到(应该在 HttpServletResponse.getOutputStream()/.getWriter() 上调用 .close() 吗?)不应该关闭流,但在这种情况下应该刷新响应吗?

不一定假设这是手头的目标:我的一般问题是我需要为客户端浏览器设置一个 cookie,但 cookie 的值取决于呈现响应内容时发生的事情(发生在 Struts 1.0 中的事情)操作,然后在 Velocity 模板中) - 我知道只有在经历了整个(Servlet -> HTML 渲染)流程之后我想要设置的 cookie 值。

请启发我。谢谢。

4

1 回答 1

-2

看起来没有人准备好接受这个,我会尝试至少提供我的观点。

在我回答你的问题之前首先,让我们看一下 servlet 过滤器的主要任务。

  • 查询请求并采取相应措施。
  • 阻止请求和响应对进一步传递。
  • 修改请求头和数据。您可以通过提供请求的定制版本来做到这一点。
  • 修改响应头和数据。您可以通过提供自定义版本的响应来做到这一点。

来源:http ://docs.oracle.com/javaee/6/tutorial/doc/bnagb.html

现在回到您的问题,您可以通过自定义响应 aka 来修改响应标头ResponseWrapper

查看您的代码,您尝试做的是修改原始响应而不是修改自定义响应,并且哪个(将 cookie 添加到原始响应)是不正常的。

因此,正确的做法是在您的自定义中添加 cookie,如下例所示。

   private class CustomResponseWrapper extends HttpServletResponseWrapper {

        private Collection<Cookie> myCookies = new ArrayList<Cookie>();

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

        @Override
        public void addCookie(Cookie cookie) {
            super.addCookie(cookie);
            myCookies.add(cookie);
        }
    }
于 2012-08-31T21:15:30.223 回答