我有一个自定义标签,它进行一些处理,然后设置一个 cookie。但是,cookie 没有被设置,我不知道为什么。另一位开发人员指出,由于我们使用的是模板系统,即标签评估点,响应标头已经作为包含的一部分被刷新。由于已发送标头,因此看起来无法添加 cookie(但是,当我尝试这样做时,不会引发任何状态异常)。有没有解决的办法?这听起来可能是问题吗?
4 回答
就像其他人所说的那样,您真的希望一开始就避免这样做。您可能想要一个不错的 MVC 类型的模型,其中您有一些 servlet 来完成您的繁重工作,例如数据库和 cookie 等等,然后将控制权传递给实际呈现响应的 JSP。由于在您的 servlet 完成之前不会调用 JSP 来生成 HTML,因此您不应该像这样陷入困境。
setCookie 在失败时没有告诉您,这有点蹩脚,但您可能不希望它破坏整个页面也是有道理的。ServletResponse.isCommitted() 将告诉您标头是否已写入,因此您的 setCookie() 调用是否会失败。
如果您处于困境并且绝对需要能够做到这一点(当您寻找更好的解决方案时),您可以创建一个 servlet 过滤器来缓冲内存中的响应,直到设置 cookie 之后。模式将是这样的:
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 需要实现 HttpServletResponse 并基本上将所有内容保存在内存中,直到您明确刷新它为止。那时它将写出标头、cookie 和缓冲的响应正文。
这将完全有效,但它会导致您的 Web 服务器使用大量额外的内存,因为它必须为每个请求在内存中缓冲整个响应体。此外,您的页面加载速度会变慢,因为在您的页面完全完成之前,服务器无法开始向客户端浏览器发送任何内容。坏juju我的朋友。
好吧,HTTP cookie 是 HTTP 标头的一部分,所以这肯定是您的问题。因此,在刷新 HTTP 标头后,您根本无法编写 cookie。
您刷新而不使用响应缓冲的任何具体原因?或者,尝试确保在刷新之前修改标题并添加 cookie。
我想一个可能的解决方法是发出 JavaScript 来设置 cookie。这种方法当然存在明显的问题。一个类似的技巧是包含一个 1x1 像素的 webbug,它在加载时设置一个 cookie。
我建议让 JSP(和类似的)只关心创建页面视图。并且还保持很少的会话状态。
HTTP 还知道在正文之后添加的页脚要像标头一样处理(相同格式)。不幸的是,HttpServletResponse 没有 addFooter 方法(例如,Resin API 有)。没有 api 会很困难。没有机会简单地将其添加到正文中 - 这将被解析为正文,而不是页脚。对不起。
如果您为浏览器编写 html,也许您可以在页面末尾(之前</html>
)包含一段 javascript 来设置 cookie。