首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

Tomcat源码分析(9)-Session管理

2012-07-31 
Tomcat源码分析(九)--Session管理在明白Tomcat的Session机制之前,先要了解Session,Cookie,JSESSIONID这几

Tomcat源码分析(九)--Session管理
       在明白Tomcat的Session机制之前,先要了解Session,Cookie,JSESSIONID这几个概念。JSESSIONID是一个唯一标识号,用来标识服务器端的Session,也用来标识客户端的Cookie,客户端和服务器端通过这个JSESSIONID来一一对应。这里需要说明的是Cookie已经包含JSESSIONID了,可以理解为JSESSIONID是Cookie里的一个属性。让我假设一次客户端连接来说明我对个这三个概念的理解:     Http连接本身是无状态的,即前一次发起的连接跟后一次没有任何关系,是属于两次独立的连接请求,但是互联网访问基本上都是需要有状态的,即服务器需要知道两次连接请求是不是同一个人访问的。如你在浏览淘宝的时候,把一个东西加入购物车,再点开另一个商品页面的时候希望在这个页面里面的购物车还有上次添加进购物车的商品。也就是说淘宝服务器会知道这两次访问是同一个客户端访问的。     客户端第一次请求到服务器连接,这个连接是没有附带任何东西的,没有Cookie,没有JSESSIONID。服务器端接收到请求后,会检查这次请求有没有传过来JSESSIONID或者Cookie,如果没有JSESSIONID和Cookie,则服务器端会创建一个Session,并生成一个与该Session相关联的JSESSIONID返回给客户端,客户端会保存这个JSESSIONID,并生成一个与该JSESSIONID关联的Cookie,第二次请求的时候,会把该Cookie(包含JSESSIONID)一起发送给服务器端,这次服务器发现这个请求有了Cookie,便从中取出JSESSIONID,然后根据这个JSESSIONID找到对应的Session,这样便把Http的无状态连接变成了有状态的连接。但是有时候浏览器(即客户端)会禁用Cookie,我们知道Cookie是通过Http的请求头部的一个cookie字段传过去的,如果禁用,那么便得不到这个值,JSESSIONID便不能通过Cookie传入服务器端,当然我们还有其他的解决办法,url重写和隐藏表单,url重写就是把JSESSIONID附带在url后面传过去。隐藏表单是在表单提交的时候传入一个隐藏字段JSESSIONID。这两种方式都能把JSESSIONID传过去。     下面来看Tomcat是怎么实现以上流程的。从Tomcat源码分析(二)--连接处理可知,连接请求会交给HttpProcessor的process方法处理,在此方法有这么几句:

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管理器其他的东西(持久化和分布式)。

1楼Wentasy3天前 18:23
学习了,分析得不错!顶一个。
Re: haitao111313前天 08:14
回复Wentasyn多谢支持~

热点排行