zoukankan      html  css  js  c++  java
  • Tomcat中的session实现

    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。。。

  • 相关阅读:
    cliconfg
    SQL 校验身份证格式
    常用MIME类型汇总
    SqlBulkCopy批量将Excel(Aspose)数据导入至SQL Server
    C#生成图片验证码
    SqlServer PIVOT函数快速实现行转列,UNPIVOT实现列转行
    SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别
    C#常用加密方式
    CURSOR 游标使用示例
    linux命令
  • 原文地址:https://www.cnblogs.com/frankyou/p/9066416.html
Copyright © 2011-2022 走看看