zoukankan      html  css  js  c++  java
  • 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生成的配置。

  • 相关阅读:
    vue使用elementui合并table
    使用layui框架导出table表为excel
    vue使用elementui框架,导出table表格为excel格式
    前台传数据给后台的几种方式
    uni.app图片同比例缩放
    我的博客
    【C语言】取16进制的每一位
    SharePoint Solution 是如何部署的呢 ???
    无效的数据被用来用作更新列表项 Invalid data has been used to update the list item. The field you are trying to update may be read only.
    SharePoint 判断用户在文件夹上是否有权限的方法
  • 原文地址:https://www.cnblogs.com/secbook/p/2655154.html
Copyright © 2011-2022 走看看