• jetty对sessionId的处理分析


    jetty7对sessionId的处理,首先入口在SessionHandler.java的doScope方法,jetty的源码分析可以参考这篇http://zhwj184.iteye.com/admin/blogs/1161542

     /* ------------------------------------------------------------ */
        /*
         * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
         */
        @Override
        public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
                throws IOException, ServletException
        {
            setRequestedId(baseRequest,request);
    
            SessionManager old_session_manager=null;
            HttpSession old_session=null;
    
            try
            {
                old_session_manager = baseRequest.getSessionManager();
                old_session = baseRequest.getSession(false);
    
                if (old_session_manager != _sessionManager)
                {
                    // new session context
                    baseRequest.setSessionManager(_sessionManager);
                    baseRequest.setSession(null);
                }
    
                // access any existing session
                HttpSession session=null;
                if (_sessionManager!=null)
                {
                    session=baseRequest.getSession(false);
                    if (session!=null)
                    {
                        if(session!=old_session)
                        {
                            HttpCookie cookie = _sessionManager.access(session,request.isSecure());
                            if (cookie!=null ) // Handle changed ID or max-age refresh
                                baseRequest.getResponse().addCookie(cookie);
                        }
                    }
                    else
                    {
                        session=baseRequest.recoverNewSession(_sessionManager);
                        if (session!=null)
                            baseRequest.setSession(session);
                    }
                }
    
                if(Log.isDebugEnabled())
                {
                    Log.debug("sessionManager="+_sessionManager);
                    Log.debug("session="+session);
                }
    
                // start manual inline of nextScope(target,baseRequest,request,response);
                if (_nextScope!=null)
                    _nextScope.doScope(target,baseRequest,request, response);
                else if (_outerScope!=null)
                    _outerScope.doHandle(target,baseRequest,request, response);
                else 
                    doHandle(target,baseRequest,request, response);
                // end manual inline (pathentic attempt to reduce stack depth)
                
            }
            finally
            {
                HttpSession session=request.getSession(false);
    
                if (old_session_manager != _sessionManager)
                {
                    //leaving context, free up the session
                    if (session!=null)
                        _sessionManager.complete(session);
                    
                    // Leave last session in place
                    if (old_session_manager!=null )
                    {
                        baseRequest.setSessionManager(old_session_manager);
                        baseRequest.setSession(old_session);
                    }
                }
            }
        }

    setRequestedId(baseRequest,request); 就是从request请求中获取sessionId的过程,首先是从cookie中获取,获取不到再从url中获取,是否设置useCookie,也可以通过配置文件配置

      /* ------------------------------------------------------------ */
        /** Look for a requested session ID in cookies and URI parameters
         * @param baseRequest
         * @param request
         */
        protected void setRequestedId(Request baseRequest, HttpServletRequest request)
        {
            String requested_session_id=request.getRequestedSessionId();
            if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()) || requested_session_id!=null)
                return;
    
            SessionManager sessionManager = getSessionManager();
            boolean requested_session_id_from_cookie=false;
            HttpSession session=null;
    
            // Look for session id cookie
            if (_sessionManager.isUsingCookies())
            {
                Cookie[] cookies=request.getCookies();
                if (cookies!=null && cookies.length>0)
                {
                    for (int i=0;i<cookies.length;i++)
                    {
                        if (sessionManager.getSessionCookie().equalsIgnoreCase(cookies[i].getName()))
                        {
                            if (requested_session_id!=null)
                            {
                                // Multiple jsessionid cookies. Probably due to
                                // multiple paths and/or domains. Pick the first
                                // known session or the last defined cookie.
                                if (sessionManager.getHttpSession(requested_session_id)!=null)
                                    break;
                            }
    
                            requested_session_id=cookies[i].getValue();
                            requested_session_id_from_cookie = true;
                            if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie");
                            
                            session=sessionManager.getHttpSession(requested_session_id);
                            if (session!=null)
                                baseRequest.setSession(session);
                        }
                    }
                }
            }
    
            if (requested_session_id==null || session==null)
            {
                String uri = request.getRequestURI();
    
                String prefix=sessionManager.getSessionIdPathParameterNamePrefix();
                if (prefix!=null)
                {
                    int s = uri.indexOf(prefix);
                    if (s>=0)
                    {   
                        s+=prefix.length();
                        int i=s;
                        while (i<uri.length())
                        {
                            char c=uri.charAt(i);
                            if (c==';'||c=='#'||c=='?'||c=='/')
                                break;
                            i++;
                        }
    
                        requested_session_id = uri.substring(s,i);
                        requested_session_id_from_cookie = false;
                        if(Log.isDebugEnabled())
                            Log.debug("Got Session ID "+requested_session_id+" from URL");                    
                    }
                }
            }
    
            baseRequest.setRequestedSessionId(requested_session_id);
            baseRequest.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
        }

     sessionId的默认参数名为:JSESSIONID

        /**
         * @return the session cookie name, by default "JSESSIONID".
         * @see #setSessionCookie(String)
         */
        public String getSessionCookie();
        /**
         * @return a formatted version of {@link #getSessionIdPathParameterName()}, by default
         *         ";" + sessionIdParameterName + "=", for easier lookup in URL strings.
         * @see #getSessionIdPathParameterName()
         */
        public String getSessionIdPathParameterNamePrefix();

    而如果sessionId不存在,同样也是在request.getSession的时候才生成session,并且把sessionId的信息存入cookjie中

    package org.eclipse.jetty.server;
    
    
    public class Request implements HttpServletRequest{
    
    ......
     /* ------------------------------------------------------------ */
        /* 
         * @see javax.servlet.http.HttpServletRequest#getSession()
         */
        public HttpSession getSession()
        {
            return getSession(true);
        }
    
        /* ------------------------------------------------------------ */
        /* 
         * @see javax.servlet.http.HttpServletRequest#getSession(boolean)
         */
        public HttpSession getSession(boolean create)
        {
            if (_sessionManager==null && create)
                throw new IllegalStateException("No SessionManager");
            
            if (_session != null && _sessionManager!=null && _sessionManager.isValid(_session))
                return _session;
            
            _session=null;
            
            String id=getRequestedSessionId();
            
            if (id != null && _sessionManager!=null)
            {
                _session=_sessionManager.getHttpSession(id);
                if (_session == null && !create)
                    return null;
            }
            
            if (_session == null && _sessionManager!=null && create )
            {
                _session=_sessionManager.newHttpSession(this);
                HttpCookie cookie=_sessionManager.getSessionCookie(_session,getContextPath(),isSecure());
                if (cookie!=null)
                    _connection.getResponse().addCookie(cookie);
            }
            
            return _session;
        }
    ......
    }

    我们再看下如果session不存在,则会通过_sessionManager.newHttpSession(this);创建一个,创建过程如下:

     /* ------------------------------------------------------------ */
        /**
         * Create a new HttpSession for a request
         */
        public HttpSession newHttpSession(HttpServletRequest request)
        {
            Session session=newSession(request);
            session.setMaxInactiveInterval(_dftMaxIdleSecs);
            addSession(session,true);
            return session;
        }
      /* ------------------------------------------------------------ */
      //HashSessionManager的实现
        @Override
        protected AbstractSessionManager.Session newSession(HttpServletRequest request)
        {
            return new HashedSession(request);
        }
    
    /**
             * Session from a request.
             * 
             * @param request
             */
    //JDBCSESSIONManager的实现
            protected Session (HttpServletRequest request)
            {
                super(request);   
                _data = new SessionData(_clusterId,_attributes);
                if (_dftMaxIdleSecs>0)
                    _data.setMaxIdleMs(_dftMaxIdleSecs*1000);
                _data.setCanonicalContext(canonicalize(_context.getContextPath()));
                _data.setVirtualHost(getVirtualHost(_context));
                _data.setExpiryTime(_maxIdleMs < 0 ? 0 : (System.currentTimeMillis() + _maxIdleMs));
            }

    而通过request创建对应SESSIONID的,sessionId分为两部分:clusterId和nodeId, nodeId就是SESSIONID

     protected Session(HttpServletRequest request)
            {
                _newSession=true;
                _created=System.currentTimeMillis();
                _clusterId=_sessionIdManager.newSessionId(request,_created);
                _nodeId=_sessionIdManager.getNodeId(_clusterId,request);
                _accessed=_created;
                _lastAccessed=_created;
                _requests=1;
                Log.debug("new session & id "+_nodeId+" "+_clusterId);
            }

    JDBC的getNodeId

        /** 
         * Get the session id, including this node's id as a suffix.
         * 
         * @see org.eclipse.jetty.server.SessionIdManager#getNodeId(java.lang.String, javax.servlet.http.HttpServletRequest)
         */
        public String getNodeId(String clusterId, HttpServletRequest request)
        {
            if (_workerName!=null)
                return clusterId+'.'+_workerName;
    
            return clusterId;
        }

    Hash的getNodeId

        /* ------------------------------------------------------------ */
        /** Get the session ID with any worker ID.
         * 
         * @param clusterId
         * @param request
         * @return sessionId plus any worker ID.
         */
        public String getNodeId(String clusterId,HttpServletRequest request) 
        {
            // used in Ajp13Parser
            String worker=request==null?null:(String)request.getAttribute("org.eclipse.jetty.ajp.JVMRoute");
            if (worker!=null) 
                return clusterId+'.'+worker; 
            
            if (_workerName!=null) 
                return clusterId+'.'+_workerName;
           
            return clusterId;
        }

    jetty是做好了集群sessionId生成的配置。

  • 相关阅读:
    细说MS事务管理
    大话设计模式(含源码)下载
    CSS基础到提高(PPT、视频、源代码),网页布局不用愁
    Android开发中Layout中明明改了id,但是还出现"cannot be resolved or is not a field"的原因
    读《OO真经》有感,以及我自己的关于哲学的体会
    Web服务小试牛刀
    在Android的RaletiveLayout中,如果空间的相对位置矛盾将不显示此控件
    .net 面试题2
    敏捷软件转
    中英文标点
  • 原文地址:https://www.cnblogs.com/secbook/p/2655154.html
Copyright © 2020-2023  润新知