1.基础:

session信息是保存在服务器端,而cookie是保存在客户端(浏览器),这个是最基础的概念,如果你这一点都不知道,再去查查资料再往下读。

具体的js、java相关的session与cookie的操作,这里也不在赘述,可以百度之,这里只讲理论。


2.客户端与服务服端交互:

以下提到的“sessionid”只是一个理论上的代号,具体的实现如tomcat的默认sessionId叫:JSESSIONID当然你可以在配置文件中修改这个key,不要把sessionid当做是具体的字段只是一个理论上的代号。

想要得到session信息需要通过session的id在服务器内存中获取,当然第一次客户端访问服务器是没有对应的session信息,第一次服务端需要新建session对象然后把sessionid返回给客户端(这时sessionid存储在cookie中)。

客户端请求服务器的时会带着cookie信息到服务端,cookie里面存储的有sessionid,服务端通过请求信息中的cookie信息得到sessionid再根据sessionid从内存中获取session信息。

所以说如果浏览器禁用cookie也就是说客户端访问服务器,服务器端获取不到cookie信息,因此也获取不到sessionid信息,最终的结果是获取不到session信息(这里忽略通过url传递sessionid这种方法,因为很少人会用这种方法)。如果浏览器禁用cookie有些需要登录的网站就无法获取session信息,无法验证登录信息,此时不能登录网站。

可以试验一下,禁用浏览器的cookie(不同类型的浏览器禁用方法不同),大部分网站都无法登录。


3.具体实现:

服务器获取session信息用request.getSession()方法,可以看一下底层是怎么实现的。

以tomcat为例

RequestFacade类的getsession方法,需下载tomcat的catalina.jar的源码或者反编译

方法中调用的是Request的getsession方法再往下找




java swing Shell 获取里面元素 java获取session的方法_tomcat组播实现session一致性


很明显服务端是根据sessionid从内存中取,这里只截取关键代码,如果感兴趣可以下载tomcat源码详细看


java swing Shell 获取里面元素 java获取session的方法_tomcat组播实现session一致性_02


在往下看requestSessionId是怎样来的:


java swing Shell 获取里面元素 java获取session的方法_ajax获取session值_03


很明显上图看到是遍历了cookie的值获取sessionid,再往下看一下tomcat中sessionId在cookie中的key值:


java swing Shell 获取里面元素 java获取session的方法_tomcat组播实现session一致性_04


public static final String SESSION_COOKIE_NAME = 
System.getProperty("org.apache.catalina.SESSION_COOKIE_NAME", "JSESSIONID");


很明显是JSESSIONID;

所以我们在浏览器调试的时候看到的cookie中的JSESSIONID的值就是服务端的sessionid。

以上验证方法可以找一个网站登录,登录之后用浏览器F12查看cookie信息里面有JSESSIONID的信息。

注意:静态资源不通过servlet可以访问的资源,明显的是不会经过服务端的代码处理,所以不会有sessionid相关的信息。

下面把tomcat生成sessionid的方法粘贴出来,有兴趣可以深入研究一下:


protected synchronized String generateSessionId()
  {
    byte[] random = new byte[16];
    String jvmRoute = getJvmRoute();
    String result = null;
    
    StringBuffer buffer = new StringBuffer();
    do
    {
      int resultLenBytes = 0;
      if (result != null)
      {
        buffer = new StringBuffer();
        this.duplicates += 1;
      }
      for (; resultLenBytes < this.sessionIdLength; goto 73)
      {
        getRandomBytes(random);
        random = getDigest().digest(random);
        int j = 0;
        if ((j < random.length) && (resultLenBytes < this.sessionIdLength))
        {
          byte b1 = (byte)((random[j] & 0xF0) >> 4);
          byte b2 = (byte)(random[j] & 0xF);
          if (b1 < 10) {
            buffer.append((char)(48 + b1));
          } else {
            buffer.append((char)(65 + (b1 - 10)));
          }
          if (b2 < 10) {
            buffer.append((char)(48 + b2));
          } else {
            buffer.append((char)(65 + (b2 - 10)));
          }
          resultLenBytes++;j++;
        }
      }
      if (jvmRoute != null) {
        buffer.append('.').append(jvmRoute);
      }
      result = buffer.toString();
    } while (this.sessions.containsKey(result));
    return result;
  }