jetty7对sessionId的处理,首先入口在SessionHandler.java的doScope方法,jetty的源码分析可以参考这篇。
/* ------------------------------------------------------------ */ /* * @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;isessionId的默认参数名为:JSESSIONID=0) { s+=prefix.length(); int i=s; while (i
/** * @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生成的配置。