7.SessionManager(session生命周期管理)
来源:互联网 发布:网络贷款骗局 编辑:程序博客网 时间:2024/06/07 12:41
SessionManager负责管理shiro自己封装的session的生命周期。
为什么shiro要自己封装session?
1.可以为任意应用提供session支持,不依赖于底层容器
2.简单扩容session管理容器,可以实现任何数据源(redis,ehcache)来管理session,而不必担心jvm内存溢出
1.SessionManager
public interface SessionManager { //根据指定的上下文SessionContext交由SessionFactory初始化个新的session Session start(SessionContext context); //根据指定的上下文信息(SessonId..)获取一个session,如果不存在返回null,如果存在但是失效,则抛出异常SessionException Session getSession(SessionKey key) throws SessionException;}
2.AbstractSessionManager
/**AbstractSessionManager是SessionManager的顶层抽象类,主要提供Session存活时间管理的支持,默认session存活时间是30分钟deprecate this class (see SHIRO-240):这个类主要为子类提供一个常用的属性“globalSessionTimeout”的支持,最初设计是为ServletContainerSessionManager和AbstractNativeSessionManager提供session存活时间管理支持,但是ServletContainerSessionManager的实现并没有使用该“globalSessionTimeout”,这意味着只有AbstractNativeSessionManager需要使用。所以该类没有存在必要了。https://issues.apache.org/jira/browse/SHIRO-240**/public abstract class AbstractSessionManager implements SessionManager { protected static final long MILLIS_PER_SECOND = 1000; protected static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND; protected static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE; /** * Default main session timeout value, equal to {@code 30} minutes. */ public static final long DEFAULT_GLOBAL_SESSION_TIMEOUT = 30 * MILLIS_PER_MINUTE; //默认为30分钟 private long globalSessionTimeout = DEFAULT_GLOBAL_SESSION_TIMEOUT; public AbstractSessionManager() { } public long getGlobalSessionTimeout() { return this.globalSessionTimeout; } //覆盖默认session存活时间30分钟 public void setGlobalSessionTimeout(long globalSessionTimeout) { this.globalSessionTimeout = globalSessionTimeout; }}
3.AbstractNativeSessionManager
/**该类基础父类AbstractSessionManager和实现NativeSessionManager接口(session操作方法规范),提供session的start、stop、Expiration状态的触发通知。**/public abstract class AbstractNativeSessionManager extends AbstractSessionManager implements NativeSessionManager { private static final Logger log = LoggerFactory.getLogger(AbstractSessionManager.class); //SESSION状态的触发通知(start、stop、Expiration) private Collection<SessionListener> listeners; public AbstractNativeSessionManager() { this.listeners = new ArrayList<SessionListener>(); } public void setSessionListeners(Collection<SessionListener> listeners) { this.listeners = listeners != null ? listeners : new ArrayList<SessionListener>(); } @SuppressWarnings({"UnusedDeclaration"}) public Collection<SessionListener> getSessionListeners() { return this.listeners; } //实现SessionManager接口的start方法 public Session start(SessionContext context) { //创建session Session session = createSession(context); //设置session过期时间 applyGlobalSessionTimeout(session); //模板方法,子类对创建session后作出反应 onStart(session, context); //创建session成功,迭代SessionListener执行onStart通知 notifyStart(session); //返回一个包装过客户端层session, return createExposedSession(session, context); } //根据上下文SessionContext创建Session,返回的session需要持久化状态,方便以后获取使用 protected abstract Session createSession(SessionContext context) throws AuthorizationException; //设置session过期时间 protected void applyGlobalSessionTimeout(Session session) { session.setTimeout(getGlobalSessionTimeout()); //session改变模板方法,子类对session改变作出反应。如:保存改变后的session onChange(session); } //模板方法:子类对session start后作出反应 protected void onStart(Session session, SessionContext context) { } //根据sessionKey获取Session public Session getSession(SessionKey key) throws SessionException { Session session = lookupSession(key); return session != null ? createExposedSession(session, key) : null; } private Session lookupSession(SessionKey key) throws SessionException { if (key == null) { throw new NullPointerException("SessionKey argument cannot be null."); } return doGetSession(key); } //获取session,如果session为null则抛异常UnknownSessionException private Session lookupRequiredSession(SessionKey key) throws SessionException { Session session = lookupSession(key); if (session == null) { String msg = "Unable to locate required Session instance based on SessionKey [" + key + "]."; throw new UnknownSessionException(msg); } return session; } //子类实现抽象方法根据sessonKey获取session protected abstract Session doGetSession(SessionKey key) throws InvalidSessionException; //封装返回客户端层session protected Session createExposedSession(Session session, SessionContext context) { return new DelegatingSession(this, new DefaultSessionKey(session.getId())); } //封装返回客户端层session protected Session createExposedSession(Session session, SessionKey key) { return new DelegatingSession(this, new DefaultSessionKey(session.getId())); } //当session过期或者停止时,需要调用通知。再调用通知前先包装下session为不可变session,防止SessionListener修改 protected Session beforeInvalidNotification(Session session) { //ImmutableProxiedSession的实现即对session凡是有修改意向的方法进行重写为抛异常。 return new ImmutableProxiedSession(session); } //session start创建后调用SessionListener的onStart通知 protected void notifyStart(Session session) { for (SessionListener listener : this.listeners) { listener.onStart(session); } } //session stop后调用SessionListener的onStop通知 protected void notifyStop(Session session) { Session forNotification = beforeInvalidNotification(session); for (SessionListener listener : this.listeners) { listener.onStop(forNotification); } } //session Expiration后调用SessionListener的onExpiration通知 protected void notifyExpiration(Session session) { Session forNotification = beforeInvalidNotification(session); for (SessionListener listener : this.listeners) { listener.onExpiration(forNotification); } } //根据sessionKey 获取session的创建时间 public Date getStartTimestamp(SessionKey key) { return lookupRequiredSession(key).getStartTimestamp(); } //根据sessionKey 获取session最后访问时间 public Date getLastAccessTime(SessionKey key) { return lookupRequiredSession(key).getLastAccessTime(); } //根据sessionKey 获取session过期时间. 负数:则永远不过期 正数:毫秒内有效 public long getTimeout(SessionKey key) throws InvalidSessionException { return lookupRequiredSession(key).getTimeout(); } //根据sessionKey设置session过期时间 public void setTimeout(SessionKey key, long maxIdleTimeInMillis) throws InvalidSessionException { Session s = lookupRequiredSession(key); s.setTimeout(maxIdleTimeInMillis); onChange(s); } //根据sessionKey修改session最后访问时间 public void touch(SessionKey key) throws InvalidSessionException { Session s = lookupRequiredSession(key); s.touch(); onChange(s); } //根据sessionKey获取session 访问IP.. public String getHost(SessionKey key) { return lookupRequiredSession(key).getHost(); } //根据sessionKey 获取session里的设置的属性 public Collection<Object> getAttributeKeys(SessionKey key) { Collection<Object> c = lookupRequiredSession(key).getAttributeKeys(); if (!CollectionUtils.isEmpty(c)) { //如果不为空,则返回个不可修改的属性集合 return Collections.unmodifiableCollection(c); } return Collections.emptySet(); } //根据sessionKey和属性key获取值 public Object getAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException { return lookupRequiredSession(sessionKey).getAttribute(attributeKey); } //根据sessionKey、属性key、属性value设置属性值 public void setAttribute(SessionKey sessionKey, Object attributeKey, Object value) throws InvalidSessionException { if (value == null) { removeAttribute(sessionKey, attributeKey); } else { Session s = lookupRequiredSession(sessionKey); s.setAttribute(attributeKey, value); //session改变模板方法,子类对session改变作出反应。如:保存改变后的session onChange(s); } } //删除session属性值 public Object removeAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException { Session s = lookupRequiredSession(sessionKey); Object removed = s.removeAttribute(attributeKey); if (removed != null) { //session改变模板方法,子类对session改变作出反应。如:保存改变后的session onChange(s); } return removed; } //判断session是否过期 public boolean isValid(SessionKey key) { try { //检查session是否过期 checkValid(key); return true; } catch (InvalidSessionException e) { return false; } } //停止该session public void stop(SessionKey key) throws InvalidSessionException { Session session = lookupRequiredSession(key); try { if (log.isDebugEnabled()) { log.debug("Stopping session with id [" + session.getId() + "]"); } session.stop(); //执行session 停止模板方法 onStop(session, key); //执行session停止通知 notifyStop(session); } finally { afterStopped(session); } } //session停止模板方法 protected void onStop(Session session, SessionKey key) { onStop(session); } //修改session停止后的状态 protected void onStop(Session session) { onChange(session); } //在session停止后执行该方法。如:删除session protected void afterStopped(Session session) { } //检查session是否有效,即获取一个非null,非过期的session public void checkValid(SessionKey key) throws InvalidSessionException { //just try to acquire it. If there is a problem, an exception will be thrown: lookupRequiredSession(key); } //对session修改作出反应的模板方法 protected void onChange(Session s) { }}
4.AbstractValidatingSessionManager
/**AbstractValidatingSessionManager继承于AbstractNativeSessionManager且实现了ValidatingSessionManager接口,该抽象类主要提供session验证和过期session检测。**/public abstract class AbstractValidatingSessionManager extends AbstractNativeSessionManager implements ValidatingSessionManager, Destroyable { private static final Logger log = LoggerFactory.getLogger(AbstractValidatingSessionManager.class); //默认每小时检测一次 public static final long DEFAULT_SESSION_VALIDATION_INTERVAL = MILLIS_PER_HOUR; //是否开启session验证检测 protected boolean sessionValidationSchedulerEnabled; //该接口主要代理SessionManager.validateSessions()方法,定时对session验证检测。如:过期的session则销毁等 protected SessionValidationScheduler sessionValidationScheduler; //该属性是定义多长时间检测一次,这个值需要根据用户的实际情况来选择,定义的太小,则检测频繁对系统性能有影响. protected long sessionValidationInterval; public AbstractValidatingSessionManager() { //默认开启检测 this.sessionValidationSchedulerEnabled = true; //默认每小时检测一次 this.sessionValidationInterval = DEFAULT_SESSION_VALIDATION_INTERVAL; } public boolean isSessionValidationSchedulerEnabled() { return sessionValidationSchedulerEnabled; } @SuppressWarnings({"UnusedDeclaration"}) public void setSessionValidationSchedulerEnabled(boolean sessionValidationSchedulerEnabled) { this.sessionValidationSchedulerEnabled = sessionValidationSchedulerEnabled; } public void setSessionValidationScheduler(SessionValidationScheduler sessionValidationScheduler) { this.sessionValidationScheduler = sessionValidationScheduler; } public SessionValidationScheduler getSessionValidationScheduler() { return sessionValidationScheduler; } //确保sessionValidation功能是开启的且有效的 private void enableSessionValidationIfNecessary() { SessionValidationScheduler scheduler = getSessionValidationScheduler(); //如果该类允许sessionValidation功能开启且scheduler无效的,则执行enableSessionValidation创建SessionValidationScheduler if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled())) { enableSessionValidation(); } } public void setSessionValidationInterval(long sessionValidationInterval) { this.sessionValidationInterval = sessionValidationInterval; } public long getSessionValidationInterval() { return sessionValidationInterval; } @Override protected final Session doGetSession(final SessionKey key) throws InvalidSessionException { //这里我觉得会有并发问题,导致创建scheduler多次,且实现方式有问题,为什么要在使用session的地方确保每次都开启呢? enableSessionValidationIfNecessary(); log.trace("Attempting to retrieve session with key {}", key); //根据sessionKey获取session Session s = retrieveSession(key); //如果session不为null,则检测session是否有效的 if (s != null) { validate(s, key); } return s; } //根据sessionKey获取session protected abstract Session retrieveSession(SessionKey key) throws UnknownSessionException; protected Session createSession(SessionContext context) throws AuthorizationException { enableSessionValidationIfNecessary(); return doCreateSession(context); } //子类实现创建session protected abstract Session doCreateSession(SessionContext initData) throws AuthorizationException; //验证session protected void validate(Session session, SessionKey key) throws InvalidSessionException { try { doValidate(session); } catch (ExpiredSessionException ese) { //session过期异常 onExpiration(session, ese, key); throw ese; } catch (InvalidSessionException ise) { //session停止无效异常 onInvalidation(session, ise, key); throw ise; } } //处理过期session protected void onExpiration(Session s, ExpiredSessionException ese, SessionKey key) { log.trace("Session with id [{}] has expired.", s.getId()); try { onExpiration(s); //session过期通知 notifyExpiration(s); } finally { //最后处理过期session。如:删除session afterExpired(s); } } protected void onExpiration(Session session) { onChange(session); } protected void afterExpired(Session session) { } //处理无效session protected void onInvalidation(Session s, InvalidSessionException ise, SessionKey key) { if (ise instanceof ExpiredSessionException) { onExpiration(s, (ExpiredSessionException) ise, key); return; } log.trace("Session with id [{}] is invalid.", s.getId()); try { //对停止session作出处理:如:设置停止时间为最后访问时间 onStop(s); //调用session停止通知 notifyStop(s); } finally { //session停止后作出处理,如:删除session afterStopped(s); } } //执行session的验证机制,实则交由session自己的validate(); protected void doValidate(Session session) throws InvalidSessionException { if (session instanceof ValidatingSession) { ((ValidatingSession) session).validate(); } else { String msg = "The " + getClass().getName() + " implementation only supports validating " + "Session implementations of the " + ValidatingSession.class.getName() + " interface. " + "Please either implement this interface in your session implementation or override the " + AbstractValidatingSessionManager.class.getName() + ".doValidate(Session) method to perform validation."; throw new IllegalStateException(msg); } } /** * 这我也搞不懂干嘛的。。 * Subclass template hook in case per-session timeout is not based on * {@link org.apache.shiro.session.Session#getTimeout()}. * <p/> * <p>This implementation merely returns {@link org.apache.shiro.session.Session#getTimeout()}</p> * * @param session the session for which to determine session timeout. * @return the time in milliseconds the specified session may remain idle before expiring. */ protected long getTimeout(Session session) { return session.getTimeout(); } //确保sessionValidation有效 protected void enableSessionValidation() { SessionValidationScheduler scheduler = getSessionValidationScheduler(); if (scheduler == null) { //如果为null。则创建个新的SessionValidationScheduler且设置到this.SessionValidationScheduler scheduler = createSessionValidationScheduler(); setSessionValidationScheduler(scheduler); } if (log.isInfoEnabled()) { log.info("Enabling session validation scheduler..."); } //启动SessionValidationScheduler里的验证机制 scheduler.enableSessionValidation(); //开启session验证后可以作出你的逻辑处理。目前shiro没有实现任何功能,你可根据你需求来决定。 //如:记录每次开启时间 afterSessionValidationEnabled(); } //创建SessionValidationScheduler protected SessionValidationScheduler createSessionValidationScheduler() { ExecutorServiceSessionValidationScheduler scheduler; if (log.isDebugEnabled()) { log.debug("No sessionValidationScheduler set. Attempting to create default instance."); } //创建ExecutorServiceSessionValidationScheduler且设置本实例进去,因为scheduler需要代理本实例的validateSessions scheduler = new ExecutorServiceSessionValidationScheduler(this); scheduler.setInterval(getSessionValidationInterval()); if (log.isTraceEnabled()) { log.trace("Created default SessionValidationScheduler instance of type [" + scheduler.getClass().getName() + "]."); } return scheduler; } protected void afterSessionValidationEnabled() { } //销毁SessionValidation protected void disableSessionValidation() { beforeSessionValidationDisabled(); SessionValidationScheduler scheduler = getSessionValidationScheduler(); if (scheduler != null) { try { //先执行SessionValidationScheduler自己的disableSessionValidation scheduler.disableSessionValidation(); if (log.isInfoEnabled()) { log.info("Disabled session validation scheduler."); } } catch (Exception e) { if (log.isDebugEnabled()) { String msg = "Unable to disable SessionValidationScheduler. Ignoring (shutting down)..."; log.debug(msg, e); } } LifecycleUtils.destroy(scheduler); //设置this.SessionValidationScheduler为null setSessionValidationScheduler(null); } } protected void beforeSessionValidationDisabled() { } public void destroy() { disableSessionValidation(); } //所有session真正的检测验证逻辑 public void validateSessions() { if (log.isInfoEnabled()) { log.info("Validating all active sessions..."); } //用来记录当前这一批次检验到session过期或者无效的总数 int invalidCount = 0; //获取sessionDAO中当前所有存在session,包括无效、过期的 Collection<Session> activeSessions = getActiveSessions(); /** 当你用户量如果非常大时候,假如有1亿个session,那么迭代会花很长时间且在这一阶段里会影响性能.可以分批次 **/ if (activeSessions != null && !activeSessions.isEmpty()) { for (Session s : activeSessions) { try { //simulate a lookup key to satisfy the method signature. //this could probably stand to be cleaned up in future versions: SessionKey key = new DefaultSessionKey(s.getId()); //验证session validate(s, key); } catch (InvalidSessionException e) { if (log.isDebugEnabled()) { boolean expired = (e instanceof ExpiredSessionException); String msg = "Invalidated session with id [" + s.getId() + "]" + (expired ? " (expired)" : " (stopped)"); log.debug(msg); } invalidCount++; } } } if (log.isInfoEnabled()) { String msg = "Finished session validation."; if (invalidCount > 0) { msg += " [" + invalidCount + "] sessions were stopped."; } else { msg += " No sessions were stopped."; } log.info(msg); } } //获取sessionDAO中当前所有存在session,包括无效、过期的 protected abstract Collection<Session> getActiveSessions();}
5.DefaultSessionManager
/**DefaultSessionManager继承AbstractValidatingSessionManager且实现CacheManagerAware接口,该具体实现类实现缓存接口CacheManagerAware只是为了让SessionDAO使用。所有关于session的状态的改变都是交由DefaultSessionManager的sessionDAO处理。**/public class DefaultSessionManager extends AbstractValidatingSessionManager implements CacheManagerAware { private static final Logger log = LoggerFactory.getLogger(DefaultSessionManager.class); //SessionFactory用来根据上下文创建新session private SessionFactory sessionFactory; //SessionDAO实现了缓存机制,所以用户只要实现第三方缓存,不依赖于JVM,就不必担心session过多导致内存溢出 protected SessionDAO sessionDAO; //todo - move SessionDAO up to AbstractValidatingSessionManager? //缓存管理器 private CacheManager cacheManager; /** 是否删除session,如果session过期或者无效后。但是有些系统需要获取及时过期或者无效的SESSION。 默认为true。如果设置为false,需要用户自己有办法在外部去管理过期或者无效session **/ private boolean deleteInvalidSessions; public DefaultSessionManager() { this.deleteInvalidSessions = true; this.sessionFactory = new SimpleSessionFactory(); this.sessionDAO = new MemorySessionDAO(); } public void setSessionDAO(SessionDAO sessionDAO) { this.sessionDAO = sessionDAO; //设置CacheManager到SessionDAO applyCacheManagerToSessionDAO(); } public SessionDAO getSessionDAO() { return this.sessionDAO; } public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } //session过期或者无效后是否删除 public boolean isDeleteInvalidSessions() { return deleteInvalidSessions; } @SuppressWarnings({"UnusedDeclaration"}) public void setDeleteInvalidSessions(boolean deleteInvalidSessions) { this.deleteInvalidSessions = deleteInvalidSessions; } //设置缓存管理器 public void setCacheManager(CacheManager cacheManager) { this.cacheManager = cacheManager; //设置缓存管理器到SessionDAO applyCacheManagerToSessionDAO(); } private void applyCacheManagerToSessionDAO() { //如果缓存管理器和SessionDAO都不null,且SessionDAO实现了CacheManagerAware,则设置CacheManager到SessionDAO if (this.cacheManager != null && this.sessionDAO != null && this.sessionDAO instanceof CacheManagerAware) { ((CacheManagerAware) this.sessionDAO).setCacheManager(this.cacheManager); } } //根据session上下文SessionContext创建Session protected Session doCreateSession(SessionContext context) { //调用SessionFactory创建session Session s = newSessionInstance(context); if (log.isTraceEnabled()) { log.trace("Creating session for host {}", s.getHost()); } //保存session到SessionDAO create(s); return s; } //调用SessionFactory创建session protected Session newSessionInstance(SessionContext context) { return getSessionFactory().createSession(context); } //保存session到SessionDAO protected void create(Session session) { if (log.isDebugEnabled()) { log.debug("Creating new EIS record for new session instance [" + session + "]"); } sessionDAO.create(session); } @Override protected void onStop(Session session) { if (session instanceof SimpleSession) { SimpleSession ss = (SimpleSession) session; Date stopTs = ss.getStopTimestamp(); ss.setLastAccessTime(stopTs); } onChange(session); } @Override protected void afterStopped(Session session) { if (isDeleteInvalidSessions()) { delete(session); } } protected void onExpiration(Session session) { if (session instanceof SimpleSession) { ((SimpleSession) session).setExpired(true); } onChange(session); } @Override protected void afterExpired(Session session) { if (isDeleteInvalidSessions()) { delete(session); } } protected void onChange(Session session) { sessionDAO.update(session); } protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException { Serializable sessionId = getSessionId(sessionKey); if (sessionId == null) { log.debug("Unable to resolve session ID from SessionKey [{}]. Returning null to indicate a " + "session could not be found.", sessionKey); return null; } //根据sessionID从SessionDAO中获取相对应的Session Session s = retrieveSessionFromDataSource(sessionId); if (s == null) { //session ID was provided, meaning one is expected to be found, but we couldn't find one: String msg = "Could not find session with ID [" + sessionId + "]"; throw new UnknownSessionException(msg); } return s; } //获取sessionKey里的SessionID protected Serializable getSessionId(SessionKey sessionKey) { return sessionKey.getSessionId(); } //根据sessionID从SessionDAO中获取相对应的Session protected Session retrieveSessionFromDataSource(Serializable sessionId) throws UnknownSessionException { return sessionDAO.readSession(sessionId); } //删除session protected void delete(Session session) { sessionDAO.delete(session); } //获取SessionDAO的存在session protected Collection<Session> getActiveSessions() { Collection<Session> active = sessionDAO.getActiveSessions(); return active != null ? active : Collections.<Session>emptySet(); }}
6.DefaultWebSessionManager
//基于WEB的SessionManager的实现 public class DefaultWebSessionManager extends DefaultSessionManager implements WebSessionManager { private static final Logger log = LoggerFactory.getLogger(DefaultWebSessionManager.class); //Cookie基本模板 private Cookie sessionIdCookie; //是否存储sessionID到cookie中,默认没有设置存活时间,即保存在浏览器开辟的内存中,没有持久化在硬盘上 private boolean sessionIdCookieEnabled; public DefaultWebSessionManager() { Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME); //HttpOnly是防止用户通过js脚本获取cookie cookie.setHttpOnly(true); //more secure, protects against XSS attacks this.sessionIdCookie = cookie; //默认允许存储sessionID到cookie中 this.sessionIdCookieEnabled = true; } //获取模板cookie public Cookie getSessionIdCookie() { return sessionIdCookie; } @SuppressWarnings({"UnusedDeclaration"}) public void setSessionIdCookie(Cookie sessionIdCookie) { this.sessionIdCookie = sessionIdCookie; } public boolean isSessionIdCookieEnabled() { return sessionIdCookieEnabled; } @SuppressWarnings({"UnusedDeclaration"}) public void setSessionIdCookieEnabled(boolean sessionIdCookieEnabled) { this.sessionIdCookieEnabled = sessionIdCookieEnabled; } //存储sessionID到cookie中 private void storeSessionId(Serializable currentId, HttpServletRequest request, HttpServletResponse response) { if (currentId == null) { String msg = "sessionId cannot be null when persisting for subsequent requests."; throw new IllegalArgumentException(msg); } Cookie template = getSessionIdCookie(); Cookie cookie = new SimpleCookie(template); String idString = currentId.toString(); cookie.setValue(idString); cookie.saveTo(request, response); log.trace("Set session ID cookie for session with id {}", idString); } //删除浏览器SessionID cookie private void removeSessionIdCookie(HttpServletRequest request, HttpServletResponse response) { getSessionIdCookie().removeFrom(request, response); } //根据sessionID Cookie获取sessionid private String getSessionIdCookieValue(ServletRequest request, ServletResponse response) { if (!isSessionIdCookieEnabled()) { log.debug("Session ID cookie is disabled - session id will not be acquired from a request cookie."); return null; } if (!(request instanceof HttpServletRequest)) { log.debug("Current request is not an HttpServletRequest - cannot get session ID cookie. Returning null."); return null; } HttpServletRequest httpRequest = (HttpServletRequest) request; //从Cookie中读取sessionID return getSessionIdCookie().readValue(httpRequest, WebUtils.toHttp(response)); } //该方法尝试通过多种办法获取SessionID private Serializable getReferencedSessionId(ServletRequest request, ServletResponse response) { //首先在cookie中获取sessionID String id = getSessionIdCookieValue(request, response); if (id != null) { //设置获取SessionID的来源 Cookie request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE); } else { //cookie不存在,尝试通过uri中获取 id = getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME); if (id == null) { //尝试中request的参数中获取 String name = getSessionIdName(); id = request.getParameter(name); if (id == null) { id = request.getParameter(name.toLowerCase()); } } if (id != null) { //设置获取SessionID的来源 URL request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, ShiroHttpServletRequest.URL_SESSION_ID_SOURCE); } } if (id != null) { //设置SessionUD request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id); //设置SessionID有效. request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE); } return id; } //通过URI获取SessionID private String getUriPathSegmentParamValue(ServletRequest servletRequest, String paramName) { if (!(servletRequest instanceof HttpServletRequest)) { return null; } HttpServletRequest request = (HttpServletRequest)servletRequest; String uri = request.getRequestURI(); if (uri == null) { return null; } int queryStartIndex = uri.indexOf('?'); if (queryStartIndex >= 0) { //get rid of the query string uri = uri.substring(0, queryStartIndex); } int index = uri.indexOf(';'); //now check for path segment parameters: if (index < 0) { //no path segment params - return: return null; } //there are path segment params, let's get the last one that may exist: final String TOKEN = paramName + "="; uri = uri.substring(index+1); //uri now contains only the path segment params //we only care about the last JSESSIONID param: index = uri.lastIndexOf(TOKEN); if (index < 0) { //no segment param: return null; } uri = uri.substring(index + TOKEN.length()); index = uri.indexOf(';'); //strip off any remaining segment params: if(index >= 0) { uri = uri.substring(0, index); } return uri; //what remains is the value } //获取sessionid存储的名字 private String getSessionIdName() { String name = this.sessionIdCookie != null ? this.sessionIdCookie.getName() : null; if (name == null) { name = ShiroHttpSession.DEFAULT_SESSION_ID_NAME; } return name; } //封装一个基于WEB(包含request和response的支持)的 客户端层session,该方法主要用在新创建session protected Session createExposedSession(Session session, SessionContext context) { if (!WebUtils.isWeb(context)) { return super.createExposedSession(session, context); } ServletRequest request = WebUtils.getRequest(context); ServletResponse response = WebUtils.getResponse(context); SessionKey key = new WebSessionKey(session.getId(), request, response); return new DelegatingSession(this, key); } //封装一个基于WEB(包含request和response的支持)的 客户端层session,该方法主要用在获取已存在的session protected Session createExposedSession(Session session, SessionKey key) { if (!WebUtils.isWeb(key)) { return super.createExposedSession(session, key); } ServletRequest request = WebUtils.getRequest(key); ServletResponse response = WebUtils.getResponse(key); SessionKey sessionKey = new WebSessionKey(session.getId(), request, response); return new DelegatingSession(this, sessionKey); } //session start创建后保存sessionID到客户端浏览器cookie中 @Override 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."); return; } HttpServletRequest request = WebUtils.getHttpRequest(context); HttpServletResponse response = WebUtils.getHttpResponse(context); //判断是否允许存储sessionID到cookie中 if (isSessionIdCookieEnabled()) { Serializable sessionId = session.getId(); 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); //设置session为新创建 request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE); } //获取sessionID @Override public Serializable getSessionId(SessionKey key) { Serializable id = super.getSessionId(key); if (id == null && WebUtils.isWeb(key)) { //WebSessionKey中封装着request和response ServletRequest request = WebUtils.getRequest(key); ServletResponse response = WebUtils.getResponse(key); id = getSessionId(request, response); } return id; } protected Serializable getSessionId(ServletRequest request, ServletResponse response) { return getReferencedSessionId(request, response); } @Override protected void onExpiration(Session s, ExpiredSessionException ese, SessionKey key) { super.onExpiration(s, ese, key); onInvalidation(key); } @Override protected void onInvalidation(Session session, InvalidSessionException ise, SessionKey key) { super.onInvalidation(session, ise, key); onInvalidation(key); } //无效session后续操作 private void onInvalidation(SessionKey key) { ServletRequest request = WebUtils.getRequest(key); if (request != null) { request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID); } if (WebUtils.isHttp(key)) { log.debug("Referenced session was invalid. Removing session ID cookie."); removeSessionIdCookie(WebUtils.getHttpRequest(key), WebUtils.getHttpResponse(key)); } else { log.debug("SessionKey argument is not HTTP compatible or does not have an HTTP request/response " + "pair. Session ID cookie will not be removed due to invalidated session."); } } @Override protected void onStop(Session session, SessionKey key) { super.onStop(session, key); if (WebUtils.isHttp(key)) { HttpServletRequest request = WebUtils.getHttpRequest(key); HttpServletResponse response = WebUtils.getHttpResponse(key); //删除sessionID cookie removeSessionIdCookie(request, response); } else { log.debug("SessionKey argument is not HTTP compatible or does not have an HTTP request/response " + "pair. Session ID cookie will not be removed due to stopped session."); } } //用于判断是否使用serlvet的session public boolean isServletContainerSessions() { return false; }}
0 0
- 7.SessionManager(session生命周期管理)
- session的生命周期管理
- 6.2 session生命周期管理
- SessionManager
- session生命周期
- Session 生命周期
- Session 生命周期 .
- Session生命周期
- Session生命周期
- session生命周期
- Session 生命周期
- session生命周期
- session生命周期
- session生命周期
- session生命周期
- session生命周期
- session生命周期
- session生命周期
- uva 11384 二分/ 递推
- Mysql的存储引擎之:MyISAM存储引擎
- 揭秘深网和暗网:你所不知道的互联网
- 位移动画的简单使用
- 笔试的一些题目
- 7.SessionManager(session生命周期管理)
- 获取url参数
- android 自定义AttributeSet属性
- 2010年8月人事培训笔记
- 网页上的一些安全漏洞攻击的了解
- linux cut 例子
- Dynamic Web Project 的学习笔记
- Android之Ubuntu下OpenGrok 安装使用
- js读取配置文件(理解版)