简体   繁体   English

在刷新标头后,向Java中的响应中添加Cookie吗?

[英]Adding a cookie to the response in Java after the header has been flushed?

I have a custom tag that does some processing and then sets a cookie. 我有一个自定义标签,该标签会进行一些处理,然后设置一个cookie。 However, the cookie wasn't being set, and I couldn't figure out why. 但是,没有设置cookie,我也不知道为什么。 Another developer pointed out that because we're using a template system, the point at which the tag evaluates, the response header has already been flushed as a part of an include. 另一位开发人员指出,由于我们使用的是模板系统,因此标签在该点进行评估,因此响应标头已作为包含的一部分进行了刷新。 Since the header has been sent, it doesn't look possible to add the cookie (however, no state exceptions are thrown when I try to do it). 由于已经发送了标头,因此似乎无法添加cookie(但是,尝试执行此操作时不会抛出状态异常)。 Is there a way around this? 有没有解决的办法? Does this sound like that might be the problem? 听起来像是问题所在吗?

Like other folks have said, you really want to avoid having to do this in the first place. 就像其他人所说的那样,您真的想避免一开始就这样做。 You'd like maybe a nice MVC kind of model where you have some servlets that do your heavy work like database and cookies and all that, and then pass control off to a JSP that actually renders the response. 您可能希望使用一种不错的MVC模型,在该模型中,您可以使用一些servlet来完成繁重的工作,例如数据库和cookie等等,然后将控制权转交给实际呈现响应的JSP。 Since the JSP isn't called to generate HTML until after your servlets are done, you shouldn't run into grief like this. 由于只有在完成servlet之后才调用JSP生成HTML,因此您不应遇到这样的麻烦。

It is kind of lame that setCookie doesn't tell you when it fails, but it also makes sense that probably you don't want it to break your entire page. setCookie在失败时不会告诉您,这是一种la脚,但也很有意义,您可能不想让它破坏整个页面。 ServletResponse.isCommitted() will tell you if the headers are already written, and consequently if your setCookie() call will fail. ServletResponse.isCommitted()会告诉您是否已写入标头,因此告诉您setCookie()调用是否失败。

If you are in dire straits and absolutely need to be able to do this (while you look for a better solution), you could create a servlet filter to buffer the response in memory until after your cookie is set. 如果您处在困境中,并且绝对需要这样做(在寻找更好的解决方案时),则可以创建一个Servlet过滤器以将响应缓冲在内存中,直到设置了cookie。 The pattern would be something like this: 该模式将如下所示:

doFilter(request, response, chain)
{
  BufferedResponse bufferedResponse = new BufferedResponse(response);
  try
  {
     // pass control to the next filter or to the JSP/servlet servicing the request
     chain.doFilter(request, bufferedResponse);
  }
  finally
  {
     bufferedResponse.flush();
  }
}

BufferedResponse would need to implement HttpServletResponse and basically keep everything in memory until you explicitly flush it. BufferedResponse将需要实现HttpServletResponse并基本上将所有内容保留在内存中,直到您明确刷新它为止。 At that point it would write out the headers, cookies, and the buffered response body. 届时它将写出标题,cookie和缓冲的响应主体。

This will totally work, but it will cause your web server to use a bunch of extra memory since it has to buffer the entire response body in memory for every request. 这将完全起作用,但是它将导致您的Web服务器使用大量额外的内存,因为它必须为每个请求将整个响应主体缓冲在内存中。 Also, your pages will load slower since the server can't start sending anything to the client browser until after your page is completely done. 此外,由于服务器直到页面完全完成后才能开始向客户端浏览器发送任何内容,因此页面加载速度较慢。 Bad juju my friend. 坏枣,我的朋友。

Well, a HTTP cookie is part of the HTTP header, so that definitely would be your problem. 嗯,HTTP cookie是HTTP标头的一部分,所以这绝对是您的问题。 And for that reason you simply can't write a cookie after having flushed the HTTP headers. 因此,在刷新HTTP标头后,您根本无法编写Cookie。

Any specific reason you are flushing and not using response buffering? 您是否正在刷新而不使用响应缓冲的任何特定原因? Alternatively, try and make sure you modify the header and add the cookie before it gets flushed. 或者,尝试确保您修改了标题并在刷新cookie之前添加了cookie。

I guess a possible workaround would be to emit JavaScript to set the cookie. 我猜可能的解决方法是发出JavaScript来设置cookie。 There are of course obvious problems with this method. 当然,这种方法存在明显的问题。 A similar trick would be to include a 1x1 pixel webbug that sets a cookie when loaded. 一个类似的技巧是包括一个1x1像素的Webbug,该Webbug在加载时设置Cookie。

I suggest keeping JSP (and similar) concerned only with creating the page view. 我建议让JSP(及类似产品)只关注创建页面视图。 And also keeping very little session state. 并且还保持很少的会话状态。

HTTP also knows footers added after body to be handled like headers (same format). HTTP还知道在正文之后添加的页脚,以便像标头(相同格式)一样进行处理。 Unfortunately the HttpServletResponse has no addFooter method (Resin API has, for example). 不幸的是,HttpServletResponse没有addFooter方法(例如,Resin API有)。 Without an api that would be hard. 没有api很难。 No chance to simply add it to the body - that will be parsed as body, not footer. 没有机会将其简单地添加到正文中-将被解析为正文,而不是页脚。 Sorry. 抱歉。

If you write html for a browser, maybe you can include a piece of javascript at the end of the page (before </html> ) to set the cookie. 如果您为浏览器编写html,也许可以在页面末尾(在</html>之前)包含一段javascript以设置cookie。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Java Servlet中提交响应后无法转发 - Cannot forward after response has been committed in java servlet java.lang.IllegalStateException:添加`return`后提交响应后无法转发 - java.lang.IllegalStateException: Cannot forward after response has been committed after add `return` Spring boot:java.lang.IllegalStateException:响应提交后无法调用sendError() - Spring boot : java.lang.IllegalStateException: Cannot call sendError() after the response has been committed JSF 2.2 java.lang.IllegalStateException:提交响应后无法创建会话 - JSF 2.2 java.lang.IllegalStateException: Cannot create a session after the response has been committed java.lang.IllegalStateException:在servletfilter中提交响应后无法转发 - java.lang.IllegalStateException: Cannot forward after response has been committed in servletfilter 将文件上传到服务器,java.net.ProtocolException:读取响应后无法写入请求正文 - Upload File To Server, java.net.ProtocolException: cannot write request body after response has been read java.lang.IllegalStateException:在提交响应后无法转发 - java.lang.IllegalStateException: Cannot forward after response has been committed java.lang.IllegalStateException:PWC1227:提交响应后无法转发……为什么要发送? - java.lang.IllegalStateException: PWC1227: Cannot forward after response has been committed…why it was comming? Spring java.lang.IllegalStateException:在提交响应后无法创建会话 - Spring java.lang.IllegalStateException: Cannot create a session after the response has been committed java.lang.IllegalStateException:在404上提交响应后无法转发 - java.lang.IllegalStateException: Cannot forward after response has been committed on 404
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM