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生成的配置。

原文地址:https://www.cnblogs.com/secbook/p/2655154.html