web项目中业务代码入口创建session,自定义Filter 的实现类
1、业务代码入口:
public class CheckSessionFilter implements Filter {
Logger logger = LoggerFactory.getLogger(CheckSessionFilter.class);
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException {
try {
XSSRequestWrapper requestWrapper = new XSSRequestWrapper((HttpServletRequest) servletRequest);
//核心实现代码
Object userToken = requestWrapper.getSession().getAttribute(Constants.CONST_CAS_USER_TOKEN);
String token = null == userToken ? null : String.valueOf(userToken);
MDC.put("logId", UuidUtil.getShortUuid() + ((StringUtil.isNotBlank(token) && SysUserUtil.getUser() != null) ? "U" + SysUserUtil.getUserId() : ""));
filterChain.doFilter(requestWrapper, servletResponse);
} catch (Exception e) {
logger.error("PrintLogFilter.e:", e);
servletResponse.setCharacterEncoding("utf-8");
servletResponse.getWriter().write(JSON.toJSON(R.error()).toString());
} finally {
MDC.clear();
}
}
@Override
public void destroy() {
//暂时空实现
}
}
2、点击 requestWrapper.getSession() 进入:
public class HttpServletRequestWrapper extends ServletRequestWrapper implements HttpServletRequest
@Override
public HttpSession getSession() {
return this._getHttpServletRequest().getSession();//点击进入
}
3、进入
public class ShiroHttpServletRequest extends HttpServletRequestWrapper
public HttpSession getSession() {
return getSession(true);
}
进入:
public HttpSession getSession(boolean create) {
HttpSession httpSession;
if (isHttpSessions()) {
httpSession = super.getSession(false);
if (httpSession == null && create) {
//Shiro 1.2: assert that creation is enabled (SHIRO-266):
if (WebUtils._isSessionCreationEnabled(this)) {
httpSession = super.getSession(create);
} else {
throw newNoSessionCreationException();
}
}
} else {
if (this.session == null) {
//核心代码,点击进入
boolean existing = getSubject().getSession(false) != null;
Session shiroSession = getSubject().getSession(create);
if (shiroSession != null) {
this.session = new ShiroHttpSession(shiroSession, this, this.servletContext);
if (!existing) {
setAttribute(REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
}
}
}
httpSession = this.session;
}
return httpSession;
}
4、进入
public class DelegatingSubject implements Subject
显示:
进入if语句
public Session getSession(boolean create) {
if (log.isTraceEnabled()) {
log.trace("attempting to get session; create = " + create +
"; session is null = " + (this.session == null) +
"; session has id = " + (this.session != null && session.getId() != null));
}
if (this.session == null && create) {
//added in 1.2:
if (!isSessionCreationEnabled()) {
String msg = "Session creation has been disabled for the current subject. This exception indicates " +
"that there is either a programming error (using a session when it should never be " +
"used) or that Shiro's configuration needs to be adjusted to allow Sessions to be created " +
"for the current Subject. See the " + DisabledSessionException.class.getName() + " JavaDoc " +
"for more.";
throw new DisabledSessionException(msg);
}
log.trace("Starting session for host {}", getHost());
SessionContext sessionContext = createSessionContext();
Session session = this.securityManager.start(sessionContext);//核心代码
this.session = decorate(session);
}
return this.session;
}
5、点击进入:
public abstract class SessionsSecurityManager extends AuthorizingSecurityManager
public Session start(SessionContext context) throws AuthorizationException {
return this.sessionManager.start(context);//进入
}
6、进入:
public abstract class AbstractNativeSessionManager extends AbstractSessionManager implements NativeSessionManager, EventBusAware
public Session start(SessionContext context) {
Session session = createSession(context);//进入
applyGlobalSessionTimeout(session);
onStart(session, context);
notifyStart(session);
//Don't expose the EIS-tier Session object to the client-tier:
return createExposedSession(session, context);
}
7、进入
public abstract class AbstractValidatingSessionManager extends AbstractNativeSessionManager implements ValidatingSessionManager, Destroyable
protected Session createSession(SessionContext context) throws AuthorizationException {
enableSessionValidationIfNecessary();
return doCreateSession(context);//点击进入
}
8、进入
public class DefaultSessionManager extends AbstractValidatingSessionManager implements CacheManagerAware
protected Session doCreateSession(SessionContext context) {
Session s = newSessionInstance(context);
if (log.isTraceEnabled()) {
log.trace("Creating session for host {}", s.getHost());
}
create(s);//点击
return s;
}
继续:
protected void create(Session session) {
if (log.isDebugEnabled()) {
log.debug("Creating new EIS record for new session instance [" + session + "]");
}
sessionDAO.create(session);//点击进入
}
9、点击
public abstract class CachingSessionDAO extends AbstractSessionDAO implements CacheManagerAware
public Serializable create(Session session) {
Serializable sessionId = super.create(session);//点击
cache(session, sessionId);
return sessionId;
}
10、进入父类
public Serializable create(Session session) {
Serializable sessionId = doCreate(session);//进入
verifySessionId(sessionId);
return sessionId;
}
11、点击进入子类业务方法
// 创建session,并保存到数据库
@Override
protected Serializable doCreate(Session session) {
Serializable sessionId = super.doCreate(session);
redisTemplate.opsForValue().set(Contans.REDIS_SESSION_KEY + sessionId.toString(), session);
return sessionId;
}
12、创建后返回到
public abstract class AbstractNativeSessionManager extends AbstractSessionManager implements NativeSessionManager, EventBusAware
public Session start(SessionContext context) {
Session session = createSession(context);
applyGlobalSessionTimeout(session);//更新session失效时间
onStart(session, context);
notifyStart(session);
//Don't expose the EIS-tier Session object to the client-tier:
return createExposedSession(session, context);
}
进入
protected void applyGlobalSessionTimeout(Session session) {
session.setTimeout(getGlobalSessionTimeout());
onChange(session);//进入
}
13、进入
public class DefaultSessionManager extends AbstractValidatingSessionManager implements CacheManagerAware
protected void onChange(Session session) {
sessionDAO.update(session);//进入
}
14、进入
public abstract class CachingSessionDAO extends AbstractSessionDAO implements CacheManagerAware
public void update(Session session) throws UnknownSessionException {
doUpdate(session);//进入业务方法
if (session instanceof ValidatingSession) {
if (((ValidatingSession) session).isValid()) {
cache(session, session.getId());
} else {
uncache(session);
}
} else {
cache(session, session.getId());
}
}
15、点击进入
// 更新session的最后一次访问时间
@Override
protected void doUpdate(Session session) {
super.doUpdate(session);
String key = Contans.REDIS_SESSION_KEY + session.getId().toString();
redisTemplate.opsForValue().set(key, session);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
}
到此,这个业务Filter的实现类流程分析完毕,下一篇继续分析其他的过滤器,敬请期待!