自己写的controller类:
@Controller
public class UserController {
@Autowired
UserService userService;
@RequestMapping("/index.action")
@ResponseBody
public String index(HttpServletRequest req ,String name){
HttpSession session = req.getSession(true);//从这里开始解剖session,调用了RequestFacade类:getSession(boolean create)
String id = session.getId();
System.out.println("id : "+id);
Cookie[] cookies = req.getCookies(); //调用了RequestFacade类:getSession(boolean create)
// for(Cookie c :cookies){
// System.out.println(c.getValue());
// }
System.out.println(" /index.action name: "+name);
return "index";
}
}
RequestFacade类:
public HttpSession getSession(boolean create)
{
if(request == null)
throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
if(SecurityUtil.isPackageProtectionEnabled())
return (HttpSession)AccessController.doPrivileged(new GetSessionPrivilegedAction(create));
else
// 调用Request类:getSession(boolean create),request为RequestFacade类的成员变量类型为Request类
return request.getSession(create);
}
Request类:
public HttpSession getSession(boolean create)
{
Session session = doGetSession(create); //这里开始创建session
if(session != null)
return session.getSession();
else
return null;
}
protected Session doGetSession(boolean create)
{
if(context == null)
return null;
if(session != null && !session.isValid())
session = null;
if(session != null)
return session;
Manager manager = null;
if(context != null)
manager = context.getManager();
if(manager == null)
return null;
if(requestedSessionId != null)
{
try
{
session = manager.findSession(requestedSessionId);//现根据sessionId 查询,如果没有则创建
}
catch(IOException e)
{
session = null;
}
if(session != null && !session.isValid())
session = null;
if(session != null)
{
session.access();
return session;
}
}
if(!create)
return null;
if(context != null && response != null && context.getCookies() && response.getResponse().isCommitted())
throw new IllegalStateException(sm.getString("coyoteRequest.sessionCreateCommitted"));
if(connector.getEmptySessionPath() && isRequestedSessionIdFromCookie())
//根据请求中sessionID创建session,调用ManagerBase类:createSession(String sessionId)
session = manager.createSession(getRequestedSessionId());
else
//调用ManagerBase类:createSession(String sessionId)
session = manager.createSession(null); //这里是自动生成sessionID(往下看),并创建session
//创建session完成后,根据已经生成的或已有的sessionId创建cookie,并且把cookie加入response中反应给前台
if(session != null && getContext() != null && getContext().getCookies())
{
String scName = context.getSessionCookieName();
if(scName == null)
scName = Globals.SESSION_COOKIE_NAME; //拿取cookie的名字,可以自己配置,(如果没有配置cookie的名字则使用默认)
Cookie cookie = new Cookie(scName, session.getIdInternal()); //根据cookieName 和 sessionID 创建一个cookie
configureSessionCookie(cookie); //设置cookie的一些属性
response.addSessionCookieInternal(cookie, context.getUseHttpOnly());//将cookie设置到response中
}
if(session != null)
{
session.access();
return session; //返回创建的session
} else
{
return null;
}
}
//设置cookie的一些属性
// cookie的发送限制是由 domain+path 进行限制的,解决客户端访问不同的服务器,传递对应的cookie
protected void configureSessionCookie(Cookie cookie)
{
cookie.setMaxAge(-1); //设置永远不过时
Context ctxt = getContext();
String contextPath = null;
if(ctxt != null && !getConnector().getEmptySessionPath())
if(ctxt.getSessionCookiePath() != null)
contextPath = ctxt.getSessionCookiePath();
else
contextPath = ctxt.getEncodedPath();
//设置在客户端保存cookie的路径
if(contextPath != null && contextPath.length() > 0)
cookie.setPath(contextPath); //设置cookie的保存路径path(如果手动配置的话)
else
cookie.setPath("/"); //设置cookie的保存路径path,默认为根目录 /
if(ctxt != null && ctxt.getSessionCookieDomain() != null)
//设置域名domain,默认为 当前请求的域名,手动设置的时候必须以 . 开头 否者无效
//同时也暗示只能是子域名
cookie.setDomain(ctxt.getSessionCookieDomain());
if(isSecure())
cookie.setSecure(true); //设置安全模式
}
ManagerBase类:
public Session createSession(String sessionId)
{
Session session = createEmptySession();
session.setNew(true); //设置为新的创建
session.setValid(true); //设置是有效的
session.setCreationTime(System.currentTimeMillis());//设置创建的时间
//60:为秒,设置存活时间默认 sessionTimeout = 30; 30分钟
session.setMaxInactiveInterval(((Context)getContainer()).getSessionTimeout() * 60);
if(sessionId == null)
//生成sessionId,永远不会重复,因为生成的时候会:sessions.containsKey(result)
// 如果发现sessions 的key中存在了sessionID 则会重新生成,直到不存在返回生成的 sessionID
sessionId = generateSessionId();
//给当的session设置sessionId并 保存当前新创建的session对象到 Map sessions 中,sessionId 作为key,session 作为v
//保存的逻辑请看 调用了 ManagerBase类: add(Session session) 方法
session.setId(sessionId);
sessionCounter++;
SessionTiming timing = new SessionTiming(session.getCreationTime(), 0);
synchronized(sessionCreationTiming)
{
sessionCreationTiming.add(timing);
sessionCreationTiming.poll();
}
return session;
}
//将session放入容器中
public void add(Session session)
{
sessions.put(session.getIdInternal(), session); //将session放入到 Map sessions 中
int size = sessions.size();
if(size > maxActive)
synchronized(maxActiveUpdateLock)
{
if(size > maxActive)
maxActive = size;
}
}
解剖tomcat 创建session的源码就到这里吧。