Tomcat中一个会话对应一个session,其实现类是StandardSession,查看源码,可以找到一个attributes成员属性,即存储session的数据结构,为ConcurrentHashMap,支持高并发的HashMap实现;

/**
* The collection of user data attributes associated with this Session.
*/
protected Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();

那么,tomcat中多个会话对应的session是由谁来维护的呢?ManagerBase类,查看其代码,可以发现其有一个sessions成员属性,存储着各个会话的session信息:

/**
* The set of currently active Sessions for this Manager, keyed by
* session identifier.
*/
protected Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();

接下来,看一下几个重要的方法,

服务器查找Session对象的方法

客户端每次的请求,tomcat都会在HashMap中查找对应的key为JSESSIONID的Session对象是否存在,可以查看Request的doGetSession方法源码,如下源码:

先看doGetSession方法中的如下代码,这个一般是第一次访问的情况,即创建session对象,session的创建是调用了ManagerBase的createSession方法来实现的; 另外,注意response.addSessionCookieInternal方法,该方法的功能就是上面提到的往响应头写入“Set-Cookie”信息;最后,还要调用session.access方法记录下该session的最后访问时间,因为session是可以设置过期时间的

session = manager.createSession(sessionId);

// Creating a new session cookie based on that session
if ((session != null) && (getContext() != null)
&& getContext().getServletContext().
getEffectiveSessionTrackingModes().contains(
SessionTrackingMode.COOKIE)) {
Cookie cookie =
ApplicationSessionCookieConfig.createSessionCookie(
context, session.getIdInternal(), isSecure()); response.addSessionCookieInternal(cookie);
} if (session == null) {
return null;
} session.access();
return session;

再看doGetSession方法中的如下代码,这个一般是第二次以后访问的情况,通过ManagerBase的findSession方法查找session,其实就是利用map的key从ConcurrentHashMap中拿取对应的value,这里的key即requestedSessionId,也即JSESSIONID,同时还要调用session.access方法,记录下该session的最后访问时间;

if (requestedSessionId != null) {
try {
session = manager.findSession(requestedSessionId);
} catch (IOException e) {
session = null;
}
if ((session != null) && !session.isValid()) {
session = null;
}
if (session != null) {
session.access();
return (session);
}
}

在session对象中查找和设置key-value的方法

这个我们一般调用getAttribute/setAttribute方法:

getAttribute方法很简单,就是根据key从map中获取value;

setAttribute方法稍微复杂点,除了设置key-value外,如果添加了一些事件监听(HttpSessionAttributeListener)的话,还要通知执行,如beforeSessionAttributeReplaced, afterSessionAttributeReplaced, beforeSessionAttributeAdded、 afterSessionAttributeAdded。。。

最新文章

  1. Bash 会清空从父进程继承来的 OLDPWD
  2. 2016年JS面试题目汇总
  3. nginx学习(2):启动gzip、虚拟主机、请求转发、负载均衡
  4. hdu 4268 multiset+贪心
  5. Git CMD - status: Show the working tree status
  6. 【leetcode】365. Water and Jug Problem
  7. C# 二分查询
  8. IOS任务管理之NSThread使用
  9. 前端自动化测试漫长路之——Selenium初探
  10. 在线数据库表(sql语句)生成java实体类工具
  11. Java开发笔记(十一)常见的数学函数
  12. robot framework---校验新增条数功能
  13. java_jsp和servlet中乱码问题
  14. public private protected default
  15. 异步操作之 Promise 和 Async await 用法进阶
  16. day4.字符串练习题
  17. mysql ANSI_QUOTES 这个sql_mode的作用(字段可以使用双引号)
  18. 忘记ios访问限制密码
  19. IOP开发数据库--20180105整理
  20. JAVA使用Tess4J进行ocr识别

热门文章

  1. 详解Java多线程编程中LockSupport类的线程阻塞用法
  2. 聚类:层次聚类、基于划分的聚类(k-means)、基于密度的聚类、基于模型的聚类
  3. LCA算法总结
  4. mybatis之foreach用法
  5. 第二十八章 springboot + zipkin(brave定制-AsyncHttpClient)
  6. java.sql.SQLException: ORA-00932: 数据类型不一致: 应为 -, 但却获得 CLOB
  7. POJ 1265 pick定理
  8. 滴滴大数据算法大赛Di-Tech2016参赛总结
  9. Active Learning
  10. vc2008中mfc菜单、控件等汉字显示为问号或乱码的解决方法