web.xml中增加SessionListener
<listener> <listener-class>com.workbgm.common.listener.SessionListener</listener-class> </listener>
SessionListener类
package com.workbgm.common.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class SessionListener implements HttpSessionListener {
private MySessionContext context = MySessionContext.getSessionContext();
@Override
public void sessionCreated(HttpSessionEvent e) {
// context.addSession(e.getSession());
}
@Override
public void sessionDestroyed(HttpSessionEvent e) {
context.delSession(e.getSession());//只是处理session超时的情况
}
}说明:前面这一堆只是为了在session超时时,更新最新的session状态!
MySessionContenxt类
package com.workbgm.common.listener;
import com.workbgm.grid.interceptor.LoginInterceptor;
import com.workbgm.grid.model.vo.data.LoginUserInfo;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
public class MySessionContext {
private static MySessionContext context;
private Map<String, HttpSession> map;
private MySessionContext() {
map = new HashMap<>();
}
public static MySessionContext getSessionContext() {
if(context == null) {
context = new MySessionContext();
}
return context;
}
//添加
public synchronized void addSession(HttpSession session) {
if(session!= null) {
LoginUserInfo loginUserInfo = (LoginUserInfo) session.getAttribute(LoginInterceptor.SESSION_USER);
if(loginUserInfo!=null) {
//登录名-用户ID作为key,你可以定义你自己的
String key=loginUserInfo.getSysUser().getUsername()+"-"+loginUserInfo.getSysUser().getId();
HttpSession oldSession=this.getSession(key);
if(oldSession!=null) {
String newUUID= session.getAttribute(LoginInterceptor.SESSION_CSRF_TOKEN).toString();
String oldUUID = oldSession.getAttribute(LoginInterceptor.SESSION_CSRF_TOKEN).toString();
if (!newUUID.equals(oldUUID)) {//不同浏览器才处理
this.clearSession(key);
}
}
map.put(key, session);
}
}
}
//清除
public synchronized void clearSession(String key){
HttpSession oldSession=this.getSession(key);
if(oldSession!=null){
oldSession.invalidate();//让session失效
map.remove(key);
}
}
//获取
public synchronized HttpSession getSession(String key) {
if(key == null)
return null;
return map.get(key);
}
//删除
public synchronized void delSession(HttpSession session) {
if(session!= null){
LoginUserInfo loginUserInfo = (LoginUserInfo) session.getAttribute(LoginInterceptor.SESSION_USER);
if(loginUserInfo!=null) {
String key=loginUserInfo.getSysUser().getUsername()+"-"+loginUserInfo.getSysUser().getId();
clearSession(key);
}
}
}
}在用户登录的时候调用addSession方法,会踢掉之前登录的用户。
那么主动踢掉用户也很简单了,只需要增加一个UI界面,把MySessionContenxt的map展示出来,踢掉就调用clearSession方法就可以了,so easy!
2019年1月22日更新
______________________
MySessionContext的addSession方法做了更新,处理了没有关闭浏览器退出,无法重新登录的bug! 这里的SESSION_CSRF_TOKEN,为了防止CSRF攻击顺便处理了同一浏览器session区分的问题,其赋值是在用户登录的时候,形式如下: this.setSessionAttr(LoginInterceptor.SESSION_CSRF_TOKEN,java.util.UUID.randomUUID());