Servet Spec 规定了三种session tracking机制:
1.cookie (cookie name 必须是JSESSIONID)
2.url rewrite (即给URL加上,";jessionid=EDFGHGFRTYTYUI56789", e.g.)
3.如果当前处于SSL中,则servlet容器可以直接利用SSL中内置的会话跟踪机制实现自己的session
据不完全代码跟读,tomcat5.5并没有采用第3种方案(我也无法确证),所以这里只讨论前两种:
机制1: cookie
a. 创建session时 => 服务端创建cookie,并通过http-response发到客户端
//org.apache.catalina.connector.Request. doGetSession() ... //先创建session对象 // Creating a new session cookie based on that session if ((session != null) && (getContext() != null) && getContext().getCookies()) { Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME, session.getIdInternal()); //注意:cookie的domain未设置 configureSessionCookie(cookie); //这里会把cookie-path设成context-path,and make it secure if HTTPS is enabled response.addCookie(cookie); }
b.客户端发回的cookie是怎么变成session的?
//org.apache.catalina.connector.CoyoteAdapter.parseSessionCookiesId() //request被构建时会parse出session-id request.setRequestedSessionId(scookie.getValue().toString()); //org.apache.catalina.connector.Request. doGetSession() //request拿session时再根据session-id取到session对象 session = manager.findSession(requestedSessionId);
机制2: url rewrite方案
a. 把;jsessionid加到URL中
只有当发生redirect时,tomcat才会自动把jsessionid加上去;你自己在JSP写的链接时,必须自己把jessionid加上去,比如用(<c:url>这个jstl标签)
b. Tomcat怎么根据;jessionid找到对应的session对象?
//org.apache.catalina.connector.CoyoteAdapter.parseSessionId() ... ByteChunk uriBC = req.requestURI().getByteChunk(); // ";jsessionid"是request-uri的一部分,不是query int semicolon = uriBC.indexOf(match, 0, match.length(), 0); // match 就是";jsessionid"