Tomat如何实现session

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"      

  

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.