1、从哪里获取sessionid
每次请求都会尝试获取sessionid
获取流程:
DefaultWebSessionManager -->getReferencedSessionId-->getSessionIdCookieValue-->simpleCookie(JSESSIONID)
抛出问题:为什么能从cookie中获取sessionid, 请看第3点的初始化
如果sessionid不为空,则直接从CachingSessionDAO获取session
熟悉这个原理后,我们就可以通过继承DefaultWebSessionManager,自定义getSessionId逻辑实现无状态的会话,而不需要依赖cookie来获取session. --通常也必须这么干才能用于生产环境,除非是一般的企业内部系统。。
2.什么时候创建session
第一步:AbstractShiroFilter包装servletRequest为ShiroHttpServletRequest
protected ServletRequest prepareServletRequest(ServletRequest request, ServletResponse response, FilterChain chain) {
ServletRequest toUse = request;
if (request instanceof HttpServletRequest) {
HttpServletRequest http = (HttpServletRequest)request;
toUse = this.wrapServletRequest(http);
}
return toUse;
}
第二步: 第一次调用了request.getsession()都会创建一个session. 并保存到session仓库中(通常我们自定义CachingSessionDAO保存到redis中)
ShiroHttpServletRequest里面有个
public HttpSession getSession() {
return this.getSession(true);
}
3.创建完session会做哪些初始化操作:AbstractNativeSessionManager,DefaultWebSessionManager
注意:isSessionIdCookieEnabled()开关决定了是否保存sessionid到cookie
源代码:
public Session start(SessionContext context) {
Session session = this.createSession(context);
this.applyGlobalSessionTimeout(session);
this.onStart(session, context);
this.notifyStart(session);
return this.createExposedSession(session, context);
}
protected void onStart(Session session, SessionContext context) {
super.onStart(session, context);
if (!WebUtils.isHttp(context)) {
log.debug("SessionContext argument is not HTTP compatible or does not have an HTTP request/response pair. No session ID cookie will be set.");
} else {
HttpServletRequest request = WebUtils.getHttpRequest(context);
HttpServletResponse response = WebUtils.getHttpResponse(context);
if (this.isSessionIdCookieEnabled()) {
Serializable sessionId = session.getId();
this.storeSessionId(sessionId, request, response);
} else {
log.debug("Session ID cookie is disabled. No cookie has been set for new session with id {}", session.getId());
}
request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
}
}