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

  • 相关阅读:
    Scala之eq,equals,==的区别
    Spark Streaming流计算特点及代码案例
    刷题50—水壶问题
    刷题49(力扣3道题)
    刷题48——最长回文串
    刷题47——矩形重叠
    刷题46——拼写单词
    刷题45(力扣两道题)
    刷题44——岛屿的最大面积
    刷题43——最长上升子序列
  • 原文地址:https://www.cnblogs.com/frankyou/p/9066416.html
Copyright © 2020-2023  润新知