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

[经验分享] tomcat处理SESSION(转载)

[复制链接]
累计签到:21 天
连续签到:1 天
发表于 2015-8-8 12:03:10 | 显示全部楼层 |阅读模式
Session对象的创建一般是源于这样的一条语句:
Session session = request.getSession(false);或者Session session = request.getSession();如果不在乎服务器压力可能多那么一点点的话。
在Tomcat的实现中,这个request是org.apache.catalina.connector.Request类的包装类org.apache.catalina.connector.RequestFacade的对象,它的两个#getSession()方法如下:
Java代码  
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就创建出来了。
  
编辑器加载中...

运维网声明 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-95689-1-1.html 上篇帖子: 转:CXF学习笔记二:如何在Tomcat中创建、发布和访问基于CXF的服务 下篇帖子: spring + mybatis + atomikos 启动tomcat报错
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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