开发四年只会写业务代码,分布式高并发都不会还做程序员?->>>
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
Subject subject = getSubject(request, response);
if (!subject.isAuthenticated() && !subject.isRemembered()) {
// 如果没有登录,直接进行之后的流程
return true;
}
Session session = subject.getSession();
User user = (User) subject.getPrincipal();
String phone = user.getPhone();
Serializable sessionId = session.getId();
// 读取缓存没有就存入
Deque<Serializable> deque = cache.get(phone);
// 如果此用户没有session队列,也就是还没有登录过,缓存中没有
// 就new一个空队列,不然deque对象为空,会报空指针
if (deque == null) {
deque = new LinkedList<>();
}
// 如果队列里没有此sessionId,且用户没有被踢出;放入队列
if (!deque.contains(sessionId) && session.getAttribute("kickout") == null) {
// 将sessionId存入队列
deque.push(sessionId);
// 将用户的sessionId队列缓存
cache.put(phone, deque);
}
// 如果队列里的sessionId数超出最大会话数,开始踢人
while (deque.size() > maxSession) {
Serializable kickoutSessionId = null;
if (kickoutAfter) { //如果踢出后者
kickoutSessionId = deque.removeFirst();
// 踢出后再更新下缓存队列
cache.put(phone, deque);
} else { // 否则踢出前者
kickoutSessionId = deque.removeLast();
// 踢出后再更新下缓存队列
cache.put(phone, deque);
}
try {
// 获取被踢出的sessionId的session对象
DefaultSessionKey dsk = new DefaultSessionKey(kickoutSessionId);
Session kickoutSession = sessionManager.getSession(dsk);
if (kickoutSession != null) {
// 设置会话的kickout属性表示踢出了
kickoutSession.setAttribute("kickout", true);
}
} catch (Exception e) {//ignore exception
}
}
//如果被踢出了,直接退出,重定向到踢出后的地址
if ((Boolean) session.getAttribute("kickout") != null && (Boolean) session.getAttribute("kickout") == true) {
//会话被踢出了
try {
//退出登录
subject.logout();
} catch (Exception e) { //ignore
}
saveRequest(request);
Map<String, String> resultMap = new HashMap<String, String>();
// 判断是不是Ajax请求
if ("XMLHttpRequest".equalsIgnoreCase(((HttpServletRequest) request).getHeader("X-Requested-With"))) {
resultMap.put("user_status", "300");
resultMap.put("message", "您已经在其他地方登录,请重新登录!");
// 输出json串
out(response, resultMap);
} else {
// 重定向
WebUtils.issueRedirect(request, response, kickoutUrl);
}
return false;
}
return true;
}
// 获取被踢出的sessionId的session对象
DefaultSessionKey dsk = new DefaultSessionKey(kickoutSessionId);
Session kickoutSession = sessionManager.getSession(dsk);
Session kickoutSession = sessionManager.getSession(dsk);
这行代码报错
@Bean
public SecurityManager securityManager() {
logger.info("--------------shiro is load----------------");
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置realm.
securityManager.setRealm(myShiroRealm());
// 注入缓存管理器;
// 注意:开发时请先关闭,如不关闭热启动会报错
// 自定义缓存实现 使用redis
securityManager.setCacheManager(cacheManager());
// 自定义session管理 使用redis
// securityManager.setSessionManager(sessionManager()); 移除sessionManager.setCacheManager(ehCacheManager()); 由于已经启用了sessionDao,CacheManager会影响到SessionDao
//注入记住我管理器;
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
我注释的那行代码有问题,注释吧提出用户报错,不注释吧用户登录后刷新页面无法第二次获取用户信息,除非记住用户,这个问题很是纠结,麻烦大神帮忙看看!最后附上错误消息