您的位置:首页 > 其它

jetty对sessionId的处理分析

2012-07-29 10:52 696 查看
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生成的配置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: