Tomcat源码分析(九)--Session管理
在明白Tomcat的Session机制之前,先要了解Session,Cookie,JSESSIONID这几个概念。JSESSIONID是一个唯一标识号,用来标识服务器端的Session,也用来标识客户端的Cookie,客户端和服务器端通过这个JSESSIONID来一一对应。这里需要说明的是Cookie已经包含JSESSIONID了,可以理解为JSESSIONID是Cookie里的一个属性。让我假设一次客户端连接来说明我对个这三个概念的理解:
- parseConnection(socket);
- parseRequest(input, output);//解析请求行,如果有jessionid,会在方法里面解析jessionid
- if (!request.getRequest().getProtocol()
- .startsWith("HTTP/0"))
- parseHeaders(input);//解析请求头部,如果有cookie字段,在方法里面会解析cookie,
下面看parseRequest方法里面是怎么解析jessionid的,这种解析方式是针对url重写的:
- parseRequest方法:
- int semicolon = uri.indexOf(match);//match是“;JSESSIONID=”,即在请求行查找字段JSESSIONID
- if (semicolon >= 0) { //如果有JSESSIONID字段,表示不是第一次访问
- String rest = uri.substring(semicolon + match.length());
- int semicolon2 = rest.indexOf(';');
- if (semicolon2 >= 0) {
- request.setRequestedSessionId(rest.substring(0, semicolon2));//设置sessionid
- rest = rest.substring(semicolon2);
- } else {
- request.setRequestedSessionId(rest);
- rest = "";
- }
- request.setRequestedSessionURL(true);
- uri = uri.substring(0, semicolon) + rest;
- if (debug >= 1)
- log(" Requested URL session id is " +
- ((HttpServletRequest) request.getRequest())
- .getRequestedSessionId());
- } else { //如果请求行没有JSESSIONID字段,表示是第一次访问。
- request.setRequestedSessionId(null);
- request.setRequestedSessionURL(false);
- }
代码没什么说的,看url有没有JSESSIONID,有就设置request的sessionid,没有就设置为null。有再看parseHeaders方法:
- parseHeaders方法:
- .....
- ....else if (header.equals(DefaultHeaders.COOKIE_NAME)) { //COOKIE_NAME的值是cookie
- Cookie cookies[] = RequestUtil.parseCookieHeader(value);
- for (int i = 0; i < cookies.length; i++) {
- if (cookies[i].getName().equals
- (Globals.SESSION_COOKIE_NAME)) {
- // Override anything requested in the URL
- if (!request.isRequestedSessionIdFromCookie()) {
- // Accept only the first session id cookie
- request.setRequestedSessionId
- (cookies[i].getValue());//设置sessionid
- request.setRequestedSessionCookie(true);
- request.setRequestedSessionURL(false);
- if (debug >= 1)
- log(" Requested cookie session id is " +
- ((HttpServletRequest) request.getRequest())
- .getRequestedSessionId());
- }
- }
- if (debug >= 1)
- log(" Adding cookie " + cookies[i].getName() + "=" +
- cookies[i].getValue());
- request.addCookie(cookies[i]);
- }
- }
代码主要就是从http请求头部的字段cookie得到JSESSIONID并设置到reqeust的sessionid,没有就不设置。这样客户端的JSESSIONID(cookie)就传到tomcat,tomcat把JSESSIONID的值赋给request了。这个request在Tomcat的唯一性就标识了。
- ManagerBase类的findSession和createSession()方法
- public Session findSession(String id) throws IOException {
- if (id == null)
- return (null);
- synchronized (sessions) {
- Session session = (Session) sessions.get(id);//根据sessionid(即<span style="font-family: Arial; ">JSESSIONID</span>)查找session对象。
- return (session);
- }
- }
- public Session createSession() { //创建session对象
- // Recycle or create a Session instance
- Session session = null;
- synchronized (recycled) {
- int size = recycled.size();
- if (size > 0) {
- session = (Session) recycled.get(size - 1);
- recycled.remove(size - 1);
- }
- }
- if (session != null)
- session.setManager(this);
- else
- session = new StandardSession(this);
- // Initialize the properties of the new session and return it
- session.setNew(true);
- session.setValid(true);
- session.setCreationTime(System.currentTimeMillis());
- session.setMaxInactiveInterval(this.maxInactiveInterval);
- String sessionId = generateSessionId();//使用md5算法生成sessionId
- String jvmRoute = getJvmRoute();
- // @todo Move appending of jvmRoute generateSessionId()???
- if (jvmRoute != null) {
- sessionId += '.' + jvmRoute;
- session.setId(sessionId);
- }
- session.setId(sessionId);
- return (session);
- }
以上是StandardManager的管理Session的两个重要方法。这里有一个问题,Session是在什么时候生成的?仔细想想,我们编写servlet的时候,如果需要用到Session,会使用request.getSession(),这个方法最后会调用到HttpRequestBase的getSession()方法,所以这里有个重要的点:Session并不是在客户端第一次访问就会在服务器端生成,而是在服务器端(一般是servlet里)使用request调用getSession方法才生成的。但是默认情况下,jsp页面会调用request.getSession(),即jsp页面的这个属性<%@ page session="true" %>默认是true的,编译成servlet后会调用request.getSession()。所以只要访问jsp页面,一般是会在服务器端创建session的。但是在servlet里就需要显示的调用getSession(),当然是在要用session的情况。下面看这个getSession()方法:
- HttpRequestBase.getSession()
- 调用---------------》
- HttpRequestBase.getSession(boolean create)
- 调用 ----------------》
- HttpRequestBase.doGetSession(boolean create){
- if (context == null)
- return (null);
- // Return the current session if it exists and is valid
- if ((session != null) && !session.isValid())
- session = null;
- if (session != null)
- return (session.getSession());
- // Return the requested session if it exists and is valid
- Manager manager = null;
- if (context != null)
- manager = context.getManager();
- if (manager == null)
- return (null); // Sessions are not supported
- if (requestedSessionId != null) {
- try {
- session = manager.findSession(requestedSessionId);//这里调用StandardManager的findSession方法查找是否存在Session对象
- } catch (IOException e) {
- session = null;
- }
- if ((session != null) && !session.isValid())
- session = null;
- if (session != null) {
- return (session.getSession());
- }
- }
- // Create a new session if requested and the response is not committed
- if (!create)
- return (null);
- if ((context != null) && (response != null) &&
- context.getCookies() &&
- response.getResponse().isCommitted()) {
- throw new IllegalStateException
- (sm.getString("httpRequestBase.createCommitted"));
- }
- session = manager.createSession();//这里调用StandardManager的创建Session对象
- if (session != null)
- return (session.getSession());
- else
- return (null);
- }
至此,Tomcat的Session管理的大部分东西也写的差不多了,这里没有写StandardManager和StandardSession两个类以及他们的实现接口,还有继承关系等,是因为觉得这篇文章已经够长了,而且他们跟跟其他标准组件也差不多,无非是实现的具体功能不一样,比如StandardSession还有过期处理等,不过它们也跟其他组件有各种关系,比如StandardManager就跟Context容器是关联的。有机会再细细的说Session管理器其他的东西(持久化和分布式)。
Tomcat源码分析(九)--Session管理相关推荐
- tomcat源码阅读之session管理器(Manager)
一.UML图分析: (一) Session: Session保存了一个客户端访问服务器时,服务器专门为这个客户端建立一个session用来保存相关的会话信息,session有一个有效时间,这个时间默认 ...
- Tomcat源码分析--转
一.架构 下面谈谈我对Tomcat架构的理解 总体架构: 1.面向组件架构 2.基于JMX 3.事件侦听 1)面向组件架构 tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成 ...
- 云客Drupal源码分析之Session进阶
在本系列之前写过<云客Drupal源码分析之Session系统>,但那部分仅仅讲到了drupal会话的基础:Symfony的Session组件 至于drupal怎么去使用这个基础就是本主题 ...
- Tomcat源码分析
Tomcat源码分析 ` 最近深入了解了下tomcat的源码,在此记录下 文章目录 Tomcat源码分析 前言 一.Tomcat整体架构是什么? 1)分析配置文件server.xml, 2)网上盗个图 ...
- Tomcat源码分析(十)--部署器 转载
本系列转载自 http://blog.csdn.net/haitao111313/article/category/1179996 我们知道,在Tomcat的世界里,一个Host容器代表一个虚机器资源 ...
- RocketMQ4.0源码分析之-路由管理
RocketMQ4.0源码分析之-路由管理 一 前言 路由管理功能是RocketMQ的核心功能之一,涵盖了订阅管理,连接管理,负载均衡管理等一系列功能,代码布在NameServer,Broker,Pr ...
- caffe源码分析--SyncedMemory 内存管理机制
caffe源码分析–SyncedMemory 内存管理机制 SyncedMemory 是caffe中用来管理内存分配和CPU.GPU数据及同步的类,只服务于Blob类.SyncedMemory 对 ...
- Linux内核源码分析《进程管理》
Linux内核源码分析<进程管理> 前言 1. Linux 内核源码分析架构 2. 进程原理分析 2.1 进程基础知识 2.2 Linux进程四要素 2.3 进程描述符 task_stru ...
- v05.05 鸿蒙内核源码分析(任务管理) | 如何管理任务池 | 百篇博客分析HarmonyOS源码
曾子曰:"吾日三省吾身:为人谋而不忠乎?与朋友交而不信乎?传不习乎?"<论语>:学而篇 百篇博客系列篇.本篇为: v05.xx 鸿蒙内核源码分析(任务管理篇) | 如何 ...
最新文章
- 计算机网络实验五,计算机网络(实验五).docx
- QT的QScriptEngineAgent类的使用
- 开源项目SlidingMenu的使用(Android)
- 【VMCloud云平台】SCSM(六)SCSM创建服务
- [转]计算机四级网络工程师思维导图--计算机网络部分
- JQuery版本下载链接
- 蓝桥杯练习------python字符串逆序
- 忍之の爱你术 全代码
- 如何发现适合自己深度投入的领域?
- Burp Spider 使用指南
- 【交易架构day4】京东到家交易系统的演进之路
- 如何能快速看懂一个Java项目?
- FIFO,LPU,CLOCK时钟算法
- leetcode第六题 Z字形变换
- pcx游程编码、解码超详细讲解(附带java源码)
- 微软 Windows 7的“杀手锏”是智能
- 英伟达 (Nvidia) GPU 系统管理界面(SMI)
- Linux 上如何让任意普通用户执行拥有root权限的特定脚本或者程序
- 苹果CMS采集资源站
- 阿里斥资百亿参建“中国神网”,5G发展更进一步