/**
* 配置sessionmanager,由redis存储数据
*/
@Bean(name = "sessionManager")
@DependsOn(value = "lifecycleBeanPostProcessor")
public ShiroSessionManager sessionManager(@Qualifier("shiroRedisTemplate") RedisTemplate redisTemplate) {
//自定义sessionManage解决单次请求需要多次访问redis
ShiroSessionManager sessionManager = new ShiroSessionManager();
//redisSessionDao
MyRedisSessionDao redisSessionDao = new MyRedisSessionDao(SESSION_TIME,redisTemplate);
sessionManager.setSessionDAO(redisSessionDao);
//删除无效会话
sessionManager.setDeleteInvalidSessions(true);
//设置对应的cookie
SimpleCookie cookie = new SimpleCookie();
cookie.setName(COOKIE_NAME);
cookie.setMaxAge(180000);
sessionManager.setSessionIdCookie(cookie);
sessionManager.setSessionIdCookieEnabled(true);
return sessionManager;
}
需要自己重新设置SimpleCookie获取sessionId
自己实现一个sessionDao来操作redis
@Slf4j
public class MyRedisSessionDao extends AbstractSessionDAO {
/**
*Session超时时间,单位为毫秒
*/
private long expireTime = 120000;
private RedisTemplate redisTemplate;
public MyRedisSessionDao() {
super();
}
public MyRedisSessionDao(long expireTime, RedisTemplate redisTemplate) {
super();
this.expireTime = expireTime;
this.redisTemplate = redisTemplate;
}
@Override
public void update(Session session) throws UnknownSessionException {
System.out.println("===============update================");
if (session == null || session.getId() == null) {
return;
}
session.setTimeout(expireTime);
redisTemplate.opsForValue().set(RedisKey.SESSION_PREFIX+session.getId(), session, expireTime, TimeUnit.MILLISECONDS);
}
@Override
public void delete(Session session) {
System.out.println("===============delete================");
if (null == session) {
return;
}
redisTemplate.opsForValue().getOperations().delete(RedisKey.SESSION_PREFIX+session.getId());
}
/**
* 获取活跃的session,可以用来统计在线人数,如果要实现这个功能,可以在将session加入redis时指定一个session前缀,
* 统计的时候则使用keys("session-prefix*")的方式来模糊查找redis中所有的session集合
*/
@Override
public Collection<Session> getActiveSessions() {
System.out.println("==============getActiveSessions=================");
Set<String> keys = redisTemplate.keys(RedisKey.SESSION_PREFIX + "*");
List<Session> sessions = Lists.newArrayList();
for (String key : keys) {
sessions.add((Session) redisTemplate.opsForValue().get(key));
}
return sessions;
}
@Override
protected Serializable doCreate(Session session) {
System.out.println("===============doCreate================");
Serializable sessionId = this.generateSessionId(session);
this.assignSessionId(session, sessionId);
redisTemplate.opsForValue().set(RedisKey.SESSION_PREFIX+session.getId(), session, expireTime, TimeUnit.MILLISECONDS);
return sessionId;
}
@Override
protected Session doReadSession(Serializable sessionId) {
System.out.println("==============doReadSession=================");
if (sessionId == null) {
return null;
}
return (Session) redisTemplate.opsForValue().get(RedisKey.SESSION_PREFIX+sessionId);
}
public long getExpireTime() {
return expireTime;
}
public void setExpireTime(long expireTime) {
this.expireTime = expireTime;
}
public RedisTemplate getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
避免多次获取redis中的session,自己来实现一个ShiroSessionManager
@Slf4j
public class ShiroSessionManager extends DefaultWebSessionManager {
/**
* 获取session
* 优化单次请求需要多次访问redis的问题
* @param sessionKey
* @return
* @throws UnknownSessionException
*/
@Override
protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
Serializable sessionId = getSessionId(sessionKey);
ServletRequest request = null;
if (sessionKey instanceof WebSessionKey) {
request = ((WebSessionKey) sessionKey).getServletRequest();
}
if (request != null && null != sessionId) {
Object sessionObj = request.getAttribute(sessionId.toString());
if (sessionObj != null) {
log.debug("read session from request");
return (Session) sessionObj;
}
}
Session session = super.retrieveSession(sessionKey);
if (request != null && null != sessionId) {
request.setAttribute(sessionId.toString(), session);
}
return session;
}
}