tomcat StandardSession

  Tomcat中Session的实现还是比较清晰的,先看类图:




 

 其中HttpSession是Servlet Api,从类图看出来,这里使用了facade模式,StandardSessionFacade为一个门面,而 HttpSession的真正的实现类为StandardSession,它还实现了一个在tomcat内部使用的Session接口,这里讲的都是单台Tomcat的Session,tomcat集群是另外一套的代码。

      Manager接口的实现是Session的管理者,保存着这台tomcat中所有的Session.Manager在Context启动的时候被创建,被启动.

 

   在Servlet api中HttpServletRequest的getSession()方法最后面定位到的就是ManagerBase的createSession()方法,当然在这个以前,会查看是否已经存在session,有的话就直接返回了, 所以HttpServletRequest的getSession(boolean create)方法可以指定是否在没有找到session的情况下创建session。

 

 public Session createSession(String sessionId) {
        
        // Recycle or create a Session instance
        Session session = createEmptySession();

        // Initialize the properties of the new session and return it
        session.setNew(true);
        session.setValid(true);
        session.setCreationTime(System.currentTimeMillis());
        session.setMaxInactiveInterval(this.maxInactiveInterval);
        if (sessionId == null) {
            sessionId = generateSessionId();
        // FIXME WHy we need no duplication check?
        /*         
             synchronized (sessions) {
                while (sessions.get(sessionId) != null) { // Guarantee
                    // uniqueness
                    duplicates++;
                    sessionId = generateSessionId();
                }
            }
        */
            
            // FIXME: Code to be used in case route replacement is needed
            /*
        } else {
            String jvmRoute = getJvmRoute();
            if (getJvmRoute() != null) {
                String requestJvmRoute = null;
                int index = sessionId.indexOf(".");
                if (index > 0) {
                    requestJvmRoute = sessionId
                            .substring(index + 1, sessionId.length());
                }
                if (requestJvmRoute != null && !requestJvmRoute.equals(jvmRoute)) {
                    sessionId = sessionId.substring(0, index) + "." + jvmRoute;
                }
            }
            */
        }
        session.setId(sessionId);
        sessionCounter++;

        return (session);

    }
    

   首先创建一个空的Session,然后是设置各种属性,比较重要的是在sessionId没有传入的情况下,生成一个唯一的sessionId的过程。

 

  protected synchronized String generateSessionId() {

        byte random[] = new byte[16];
        String jvmRoute = getJvmRoute();
        String result = null;

        // Render the result as a String of hexadecimal digits
        StringBuffer buffer = new StringBuffer();
        do {
            int resultLenBytes = 0;
            if (result != null) {
                buffer = new StringBuffer();
                duplicates++;
            }

            while (resultLenBytes < this.sessionIdLength) {
                getRandomBytes(random);
                random = getDigest().digest(random);
                for (int j = 0;
                j < random.length && resultLenBytes < this.sessionIdLength;
                j++) {
                    byte b1 = (byte) ((random[j] & 0xf0) >> 4);
                    byte b2 = (byte) (random[j] & 0x0f);
                    if (b1 < 10)
                        buffer.append((char) ('0' + b1));
                    else
                        buffer.append((char) ('A' + (b1 - 10)));
                    if (b2 < 10)
                        buffer.append((char) ('0' + b2));
                    else
                        buffer.append((char) ('A' + (b2 - 10)));
                    resultLenBytes++;
                }
            }
            if (jvmRoute != null) {
                buffer.append('.').append(jvmRoute);
            }
            result = buffer.toString();
        } while (sessions.containsKey(result));
        return (result);

    }

     在单台tomcat的情况下,jvmRoute是null的,这个随机数产生主要是要平衡,每次要求产生都尽可能的不一样,首先是new一个byte的数组,然后先去文件里面读取随机数,如果不行的话,需要产生一个种子来初始化一个随机数生成器然后生成随机数,之后进行MD5的计算,当然还是要判断一下这个id是不是已经存在了.

 

      StandardManager还有很有意思的方法,在stop()方法中会调用unload()方法,这个方法把session的数据保存到文件中,当然也可以从文件中读书,这个文件存在于tomcat work对应项目目录下面的SESSIONS.ser文件中.

 

StandardSession中还有几个方法是对应Session Listener的,这些Session Listener是在Servlet Api中的,这样子的话,我们在外面实现这些类的时候,可以对应在Session发生变化的时候,tomcat有个回调我们类的机会

 

 

这些listener有:

HttpSessionListener  在session创建和销毁时用(StandardSession.setId(),StandardSession.expire())

HttpSessionActivationListener  在session钝化和反钝化时用(StandardSession.doUnload(),StandardSession.doload())

HttpSessionAttributeListener  在session的attributes属性发生变化时

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值