设为首页 收藏本站
查看: 1066|回复: 0

[经验分享] tomcat session管理

[复制链接]

尚未签到

发表于 2015-8-7 09:00:05 | 显示全部楼层 |阅读模式
已经成功关注 zddava 的动态


Tomcat的Session管理(一) - Session的生成
博客分类:

  • Tomcat

Tomcat配置管理ApacheAccessF#
Session对象的创建一般是源于这样的一条语句:
Session session = request.getSession(false);或者Session session = request.getSession();如果不在乎服务器压力可能多那么一点点的话。
在Tomcat的实现中,这个request是org.apache.catalina.connector.Request类的包装类org.apache.catalina.connector.RequestFacade的对象,它的两个#getSession()方法如下:



Java代码 DSC0000.png

  • public HttpSession getSession(boolean create) {  
  •     if (request == null) {  
  •         throw new IllegalStateException(  
  •                         sm.getString("requestFacade.nullRequest"));  
  •     }  
  •   
  •     if (SecurityUtil.isPackageProtectionEnabled()){  
  •         return (HttpSession)AccessController.  
  •             doPrivileged(new GetSessionPrivilegedAction(create));  
  •     } else {  
  •         return request.getSession(create);  
  •     }  
  • }  




Java代码

  • public HttpSession getSession() {  
  •     if (request == null) {  
  •         throw new IllegalStateException(  
  •                         sm.getString("requestFacade.nullRequest"));  
  •     }  
  •   
  •     return getSession(true);  
  • }  

其实差不太多,最后都会进入org.apache.catalina.connector.Request的#getSession()方法。这个方法的源代码如下:



Java代码

  • public HttpSession getSession(boolean create) {  
  •     Session session = doGetSession(create);  
  •     if (session != null) {  
  •         return session.getSession();  
  •     } else {  
  •         return null;  
  •     }  
  • }  

然后调用就到了#doGetSession()这个方法了。源代码如下



Java代码

  • protected Session doGetSession(boolean create) {  
  •     // 没有Context的话直接返回null  
  •     if (context == null)  
  •         return (null);  
  •   
  •     // 判断Session是否有效  
  •     if ((session != null) && !session.isValid())  
  •         session = null;  
  •     if (session != null)  
  •         return (session);  
  •   
  •     // 返回Manager对象,这里是StandardManager类的对象  
  •     Manager manager = null;  
  •     if (context != null)  
  •         manager = context.getManager();  
  •     if (manager == null)  
  •         return (null); // Sessions are not supported  
  •     // 判断是否有SessionID  
  •     if (requestedSessionId != null) {  
  •         try {  
  •             // 在Manager中根据SessionID查找Session  
  •             session = manager.findSession(requestedSessionId);  
  •         } catch (IOException e) {  
  •             session = null;  
  •         }  
  •         if ((session != null) && !session.isValid())  
  •             session = null;  
  •         if (session != null) {  
  •             // 更新访问时间  
  •             session.access();  
  •             return (session);  
  •         }  
  •     }  
  •   
  •     // 创建新的Session  
  •     if (!create)  
  •         return (null);  
  •     if ((context != null) && (response != null) && context.getCookies()  
  •             && response.getResponse().isCommitted()) {  
  •         throw new IllegalStateException(sm.getString("coyoteRequest.sessionCreateCommitted"));  
  •     }  
  •   
  •     // 判断是否使用 "/" 作为Session Cookie的存储路径 并且 是否SessionID来自Cookie  
  •     if (connector.getEmptySessionPath() && isRequestedSessionIdFromCookie()) {  
  •         // 创建Session  
  •         session = manager.createSession(getRequestedSessionId());  
  •     } else {  
  •         session = manager.createSession(null);  
  •     }  
  •   
  •     // 创建一个新的Session Cookies  
  •     if ((session != null) && (getContext() != null) && getContext().getCookies()) {  
  •         Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME, session.getIdInternal());  
  •         // 配置Session Cookie  
  •         configureSessionCookie(cookie);  
  •         // 在响应中加入Session Cookie  
  •         response.addCookieInternal(cookie);  
  •     }  
  •   
  •     if (session != null) {  
  •         // 更新访问时间  
  •         session.access();  
  •         return (session);  
  •     } else {  
  •         return (null);  
  •     }  
  •   
  • }  

这个方法说明了Session创建的大致过程,首先判断requestedSessionId是否存在,如果存在,那么根据这个ID去查找Session对象。如果requestedSessionId不存在或者没有取到Session,并且传递给#getSession(boolean)的参数为真,那么要创建一个新的Session,并且给客户端写回去一个Session Cookie。
首先,我感兴趣的是requestedSessionId的赋值,它到底是什么时候被赋值的呢?
还要向回看Tomcat的请求处理过程,请求曾到过这一步,org.apache.catalina.connector.CoyoteAdapter的#service()方法。里边有这样一句方法调用:postParseRequest(req, request, res, response)。就是这一步处理了SessionID的获取,这个方法调用了#parseSessionId()和parseSessionCookiesId()这两个方法,就是它对Session ID进行了提取,源代码分别如下:



Java代码

  • protected void parseSessionId(org.apache.coyote.Request req, Request request) {  
  •   
  •     ByteChunk uriBC = req.requestURI().getByteChunk();  
  •     // 判断URL中是不是有";jsessionid="这个字符串  
  •     int semicolon = uriBC.indexOf(match, 0, match.length(), 0);  
  •   
  •     if (semicolon > 0) {  
  •         // Parse session ID, and extract it from the decoded request URI  
  •         // 在URL中提取Session ID  
  •         int start = uriBC.getStart();  
  •         int end = uriBC.getEnd();  
  •   
  •         int sessionIdStart = semicolon + match.length();  
  •         int semicolon2 = uriBC.indexOf(';', sessionIdStart);  
  •         if (semicolon2 >= 0) {  
  •             request.setRequestedSessionId(new String(uriBC.getBuffer(), start + sessionIdStart,  
  •                     semicolon2 - sessionIdStart));  
  •             byte[] buf = uriBC.getBuffer();  
  •             for (int i = 0; i < end - start - semicolon2; i++) {  
  •                 buf[start + semicolon + i] = buf[start + i + semicolon2];  
  •             }  
  •             uriBC.setBytes(buf, start, end - start - semicolon2 + semicolon);  
  •         } else {  
  •             request.setRequestedSessionId(new String(uriBC.getBuffer(), start + sessionIdStart,  
  •                     (end - start) - sessionIdStart));  
  •             uriBC.setEnd(start + semicolon);  
  •         }  
  •         // 设定Session ID来自于URL  
  •         request.setRequestedSessionURL(true);  
  •   
  •     } else {  
  •         request.setRequestedSessionId(null);  
  •         request.setRequestedSessionURL(false);  
  •     }  
  •   
  • }  




Java代码

  • protected void parseSessionCookiesId(org.apache.coyote.Request req, Request request) {  
  •     Context context = (Context) request.getMappingData().context;  
  •     if (context != null && !context.getCookies())  
  •         return;  
  •   
  •     // 返回Cookie  
  •     Cookies serverCookies = req.getCookies();  
  •     int count = serverCookies.getCookieCount();  
  •     if (count = 0) && (sessions.size() >= maxActiveSessions)) {  
  •         rejectedSessions++;  
  •         throw new IllegalStateException(sm.getString("standardManager.createSession.ise"));  
  •     }  
  •     return (super.createSession(sessionId));  
  • }  

最后调用到了它的基类的#createSession()方法了。



Java代码

  • public Session createSession(String sessionId) {  
  •     // 创建一个新的Session  
  •     Session session = createEmptySession();  
  •   
  •     // 初始化Session的属性  
  •     session.setNew(true);  
  •     session.setValid(true);  
  •     session.setCreationTime(System.currentTimeMillis());  
  •     session.setMaxInactiveInterval(this.maxInactiveInterval);  
  •     // 如果Session ID为null,那么就生成一个  
  •     if (sessionId == null) {  
  •         sessionId = generateSessionId();  
  •     }  
  •     session.setId(sessionId);  
  •     sessionCounter++;  
  •   
  •     return (session);  
  •   
  • }  

通过上述过程,一个新的Session就创建出来了。

http://zddava.iteye.com/blog/311053

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-94989-1-1.html 上篇帖子: 用命令行(批处理)启动Tomcat, JBoss 下篇帖子: tomcat单机多实例部署
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表