java - B 不能转换为 org.apache.shiro.session.Session
问题描述
这是一个Spring+Shiro+Redis的项目,运行一段时间后每次都会报这个错误。
为此,我收到此错误
2021-09-02 11:16:39.273 - INFO [idationThread-1] stractValidatingSessionManager : Validating all active sessions...
2021-09-02 11:16:39.290 -ERROR [idationThread-1] viceSessionValidationScheduler : Error while validating the session
java.lang.ClassCastException: [B cannot be cast to org.apache.shiro.session.Session
at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.validateSessions(AbstractValidatingSessionManager.java:283) ~[shiro-core-1.7.0.jar:1.7.0]
at org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler.run(ExecutorServiceSessionValidationScheduler.java:120) [shiro-core-1.7.0.jar:1.7.0]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_151]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_151]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_151]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_151]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_151]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_151]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_151]
解决方案
问题原因
org.apache.shiro.session.mgt.AbstractValidatingSessionManager
方法得到的数据类型getactivesessions()
不对(可能是我用错了)。然后,在执行时session s: activesessions
,会发生错误B cannot be cast to org.apache.shiro.session.Session
。
public void validateSessions() {
if (log.isInfoEnabled()) {
log.info("Validating all active sessions...");
}
int invalidCount = 0;
Collection<Session> activeSessions = getActiveSessions();
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());
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);
}
}
解决方案:</p>
我们需要重写getactivesessions()
自定义 Dao 中的方法。
我的RedisCachingShiroSessionDao
代码
public class RedisCachingShiroSessionDao extends EnterpriseCacheSessionDAO {
@Resource
private RedisTemplate<String,Object> redisTemplate;
...
@Override
public Collection<Session> getActiveSessions() {
Set<String> keys = this.redisTemplate.keys(this.prefix + "*");
if (keys != null && !keys.isEmpty()) {
List<Object> sessions = this.redisTemplate.opsForValue().multiGet(keys);
if (sessions != null) {
return sessions.stream().map(o -> (Session) o).collect(Collectors.toList());
}
}
return Collections.emptySet();
}
}
推荐阅读
- javascript - 有人可以解释一下 Javascript 中 replace() 方法的这种特殊用法吗?
- python - 模拟两个六面骰子滚动1000次并将总和值存储在文件中的python程序
- flutter - 如何在颤动折线图 X 轴中添加字符串范围?
- visual-studio-code - 重新打开扩展欢迎页面 VS Code?
- vert.x - 如何实现“实时”静态客户端资源(以防止在开发期间在 CSS 和 JS 更改之间重新启动项目服务器)?
- bash - 适用于 Linux 的 Windows 子系统 - 在启动时将参数传递给命令
- python - 如何在文件中查找特定文本,然后在 Python 中找到它时返回其受尊重的文件名?
- nginx - 我无法在 ubuntu 上正确配置 nginx 服务器
- validation - 验证数据时出错:[ValidationError(Deployment): unknown field "\u00a0 name" during `kubectl apply -f myfile.yaml`
- autohotkey - AHK 代码问题 - 在 AHK 中导入和定义变量?