如果你还在为上面的错误而烦恼。还要听从网上说找合适的版本去解决。来到这篇文章,你的电脑算是保住了。
让我们来分析下问题所在。其实就是实体类RedisSessionDAO中方法getActiveSessions具体是
redisManager.keys行的问题。有兴趣的可以继续找redisManager.keys下面的代码。
如果考虑换版本之类的,有可能对整体框架都是有影响的。所以我们要换种思路。既然是shiro内在的redis出的问题。那我能不能摒弃他们的redis。答案是:当然可以了!
做法就是自定义个RedisSessionDAO,重写他们的方法。
?然后你在按照下面这样获取活跃的用户,去处理自己的逻辑
?项目经理都夸你是个人才。
?好了。代码给你放下面了。有问题具体私我。
package com.changfa.config.shiro;
import com.changfa.config.RedisConfig;
import com.changfa.constants.UserConstants;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.crazycake.shiro.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @author wwz
*/
public class CustomRedisSessionDAO extends RedisSessionDAO{
private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class);
private static final String DEFAULT_SESSION_KEY_PREFIX = "shiro:session:";
private String keyPrefix = "shiro:session:";
private static final long DEFAULT_SESSION_IN_MEMORY_TIMEOUT = 1000L;
private long sessionInMemoryTimeout = 1000L;
private static final int DEFAULT_EXPIRE = 1800;
private int expire = 1800;
private static final int MILLISECONDS_IN_A_SECOND = 1000;
private IRedisManager redisManager;
private RedisSerializer keySerializer = new StringSerializer();
private RedisSerializer valueSerializer = new ObjectSerializer();
private static ThreadLocal sessionsInThread = new ThreadLocal();
private RedisConfig.ByteRedisTemplate<String,Byte[]> redisTemplate;
public CustomRedisSessionDAO() {
}
@Override
public void update(Session session) throws UnknownSessionException {
this.saveSession(session);
}
private void saveSession(Session session) throws UnknownSessionException {
if (session != null && session.getId() != null) {
if ((long)(this.expire * 1000) < session.getTimeout()) {
logger.warn("Redis session expire time: " + this.expire * 1000 + " is less than Session timeout: " + session.getTimeout() + " . It may cause some problems.");
}
byte[] value = new byte[0];
try {
value = valueSerializer.serialize(session);
redisTemplate.opsForValue().set(this.getRedisSessionKey(session.getId()),value,this.expire, TimeUnit.SECONDS);
} catch (SerializationException e) {
e.printStackTrace();
}
// this.redisManager.set(key, value, this.expire);
} else {
logger.error("session or session id is null");
throw new UnknownSessionException("session or session id is null");
}
}
@Override
public void delete(Session session) {
if (session != null && session.getId() != null) {
try {
redisTemplate.delete(this.getRedisSessionKey(session.getId()));
//this.redisManager.del(this.keySerializer.serialize(this.getRedisSessionKey(session.getId())));
} catch (Exception var3) {
logger.error("delete session error. session id=" + session.getId());
}
} else {
logger.error("session or session id is null");
}
}
@Override
public Collection<Session> getActiveSessions() {
HashSet sessions = new HashSet();
try {
Set<String> keys = redisTemplate.keys(this.keyPrefix + "*");
if (keys != null && keys.size() > 0) {
Iterator i$ = keys.iterator();
while(i$.hasNext()) {
String key = (String)i$.next();
Session s = (Session)valueSerializer.deserialize((byte[]) this.redisTemplate.opsForValue().get(key));
Object o = s.getAttribute(UserConstants.USER_KEY);
if(o != null){
sessions.add(s);
}
}
}
} catch (Exception var6) {
logger.error("get active sessions error.");
}
return sessions;
}
@Override
protected Serializable doCreate(Session session) {
if (session == null) {
logger.error("session is null");
throw new UnknownSessionException("session is null");
} else {
Serializable sessionId = this.generateSessionId(session);
this.assignSessionId(session, sessionId);
this.saveSession(session);
return sessionId;
}
}
@Override
protected Session doReadSession(Serializable sessionId) {
if (sessionId == null) {
logger.warn("session id is null");
return null;
} else {
Session s = this.getSessionFromThreadLocal(sessionId);
if (s != null) {
return s;
} else {
logger.debug("read session from redis");
try {
s = (Session)this.valueSerializer.deserialize((byte[]) this.redisTemplate.opsForValue().get(this.getRedisSessionKey(sessionId)));
// s = (Session)this.valueSerializer.deserialize(this.redisManager.get(this.keySerializer.serialize(this.getRedisSessionKey(sessionId))));
this.setSessionToThreadLocal(sessionId, s);
} catch (Exception var4) {
logger.error("read session error. settionId=" + sessionId);
}
return s;
}
}
}
private void setSessionToThreadLocal(Serializable sessionId, Session s) {
Map<Serializable, SessionInMemory> sessionMap = (Map)sessionsInThread.get();
if (sessionMap == null) {
sessionMap = new HashMap();
sessionsInThread.set(sessionMap);
}
SessionInMemory sessionInMemory = new SessionInMemory();
sessionInMemory.setCreateTime(new Date());
sessionInMemory.setSession(s);
((Map)sessionMap).put(sessionId, sessionInMemory);
}
private Session getSessionFromThreadLocal(Serializable sessionId) {
Session s = null;
if (sessionsInThread.get() == null) {
return null;
} else {
Map<Serializable, SessionInMemory> sessionMap = (Map)sessionsInThread.get();
SessionInMemory sessionInMemory = (SessionInMemory)sessionMap.get(sessionId);
if (sessionInMemory == null) {
return null;
} else {
Date now = new Date();
long duration = now.getTime() - sessionInMemory.getCreateTime().getTime();
if (duration < this.sessionInMemoryTimeout) {
s = sessionInMemory.getSession();
logger.debug("read session from memory");
} else {
sessionMap.remove(sessionId);
}
return s;
}
}
}
private String getRedisSessionKey(Serializable sessionId) {
return this.keyPrefix + sessionId;
}
public RedisConfig.ByteRedisTemplate getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisConfig.ByteRedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
|