我对Java中的会话管理感到困惑。当我浏览会话创建时,我在网络上找到了不同的答案,这些答案在他们自己的上下文中是正确的。我有几个基本问题。
1)在发出第一个HTTP请求时,浏览器是否创建会话ID,并发送到服务器,或者当来自浏览器的HTTP请求落在服务器上时,服务器第一次创建会话ID?
2)JSessionID是会话ID吗? 如何在浏览器中设置此ID(即在服务器和浏览器之间传递的标头)? 如何在服务器中设置此ID(在服务器内部)?
3)如果在第一次HTTP请求时服务器/浏览器创建了会话ID,那么HttpServletRequest.getSession(true)方法的作用和时间是什么? 该方法有什么用?
4)来自服务器的sessionId是作为单独的标头传递还是在Cookie标头中传递?
如果在浏览器中禁用了cookie,并且服务器通过任何方式传递了sessionId(我认为是JSessionId)(Separate Header或Cookies Header或任何其他形式),那么浏览器会做什么?在这种情况下如何建立会话?
我们是否明确需要编写用于在服务器端附加sessionId作为查询参数的代码?
我们如何在服务器端检查浏览器是否已禁用cookie?
答案 0 :(得分:5)
会话ID始终由服务器创建。但是如果浏览器需要,它可以将其切换为其他ID而服务器几乎无法找到(这就是为什么会话ID难以猜测并且是随机生成的)
只有当您(程序员)第一次尝试使用会话时,服务器才会创建会话ID。重载的getSession
方法就在那里,因此您可以在不创建会话的情况下探测会话的存在。
会话ID必须由服务器(至少一次)发送到客户端并由客户端返回(每次请求)。有很多方法可以做到(你可以考虑插件的不同方式,确切的技术对于实际的会话对象无关紧要)。
通常的方法是:
用饼干; cookie值的名称可能是JSESSIONID,但它可能是其他东西(它是可配置的)。在创建会话时,服务器发送Set-Cookie
标头(仅一次)。从那时起,由于Cookie的工作方式,浏览器会将Cookie值附加到标准Cookie
标题;
。服务器必须将参数附加到每个URL(GET)并作为每个表单的隐藏字段(GET或POST)。自动执行此过程并不容易(因为表单和链接可能由不同的库和应用程序生成),而且主要取决于程序员。但是一些技术(如JSP)对添加此参数(如JSTL中的<c:url>
)有一些支持。如果您使用其他一些演示技术或为自己生成网址,则必须检查其工作原理。
答案 1 :(得分:0)
会话是在服务器端而不是客户端(浏览器)上处理的。每当发出GET或POST请求时,都会调用某种handleRequest(HTTPRequest request, HTTPResponse)
,具体取决于您提供的映射。现在,您可以通过public HttpSession getSession()
方法获取会话。例如Session session = request.getSession();
。它返回与此请求关联的当前会话,或者如果请求没有会话,则创建一个(more)。
Servlet HTTP会话使用名称为JSESSIONID
的cookie和标识会话的值。
Servlet容器保存HttpSession对象的映射(YMMV)和这些标识符。当客户端首先发出请求时,服务器会创建一个具有唯一标识符的HttpSession对象,并将其存储在其映射中。然后在响应中添加Set-Cookie
标头。它将cookie的名称设置为JSESSIONID
,并将其值设置为刚刚创建的标识符。
客户端会收到这些cookie并将其存储在某个地方,通常是在文本文件中。向服务器发送新请求时,它可以在请求的Cookie标头中使用该cookie来通知服务器它可能已经完成了先前的请求。
当Servlet容器收到请求时,它会提取Cookie标头值,并尝试使用HttpSession
cookie中的密钥从其映射中检索JSESSIONID
对象。然后将此HttpSession
对象附加到Servlet容器创建并传递给Servlet的HttpServletRequest
对象。您可以使用setAttribute(String, Object)
和getAttribute(String)
方法来管理状态。