Session管理之超时设置和强制下线
关于Session,在Java Web开发中,为我们提供了很多⽅便,Session是由浏览器和服务器之间维护的。好吧,闲话不多说,下⾯让我们⼀步⼀步来实现它们。
(⼀)⾸先来说下Session超时时间设置的三种⽅式,这些相对来说⽐较简单:
(1)在l中设置session-config
web端登录
<session-config>
<session-timeout>2</session-timeout>
</session-config>
即交互间隔时间最长为2分钟(该处时间单位为分钟),2分钟后Attribute()获取的值为空。
(2)在Tomcat的/l中session-config,默认值为:30分钟
<session-config>
<session-timeout>30</session-timeout>
</session-config>
同上,时间单位为分钟。
(3)在Servlet中设置
HttpSession session = Session();
session.setMaxInactiveInterval(60);
即在你的程序代码中⼿动设置(该处时间单位为秒)。
优先级:Servlet中设置 &l设置 > Tomcat/l设置
(⼆)同⼀⽤户强制下线
⼤家都知道在⽬前很多的web项⽬中,⼤多数情况下都是可以让同⼀个⽤户账号在不同的登录⼊⼝登录的,但这样其实就显得不是很严谨了,毕竟信息修改等操作对于信息是否能完全即时同步还是个未知之数。所以,接下来,我要做的只是对于不同浏览器的同⼀个⽤户账号的强制下线处理,对于同⼀个浏览器暂不做考虑,先来看下⾯这张图。⼤概的了解⼀下:
从上⾯可以看出:同⼀个浏览器对于不同的账号,登录时会产⽣相同的sessionId,这也就导致了⽤户之间信息的覆盖;不同浏览器对于不同的账号登录时,登录时会产⽣不同的sessionId,这也就给了我们可操作的空间了,正是要利⽤这⼀点来进⾏判断和相应处理。
(1)添加
为了⽅便这⾥使⽤Session监控的⽅式,创建SessionListener,如下:
public class SessionListener implements HttpSessionBindingListener{
@Override
public void valueBound(HttpSessionBindingEvent event){
// TODO Auto-generated method stub
}
@Override
public void valueUnbound(HttpSessionBindingEvent event){
// TODO Auto-generated method stub
}
}
这⾥HttpSessionBindingListener和HttpSessionListener效果⼀样,⼤家可以任选其⼀。重载两个⽅法:session的创建和销毁。
当然,在l中添加相应配置是必不可少的:
<listener>
<listener-class&ki.util.SessionListener</listener-class>
</listener>
由于sessionId和userId需要存储,⽅便后⾯的判断,我们在上⾯的类中添加两个Map,如下:
//保存username和session的映射
public static HashMap<String,Session> MAP1 = new HashMap<String,Session>();
//保存sessionID和username的映射
public static HashMap MAP2 = new HashMap();
最后,⽤户登录验证成功时需要调⽤⼀个⽅法来判断是否强制下线:
public static void userLogin(Session session,String sUserName){
//已登录
ainsValue(sUserName)){
Session l_session = (sUserName);
//不同浏览器,同⼀⽤户(强制下线前⼀个)
if(l_session != null && Id() != Id()){
l_session.setAttribute("msg", "您的账号已在另⼀处登录!");
MAP2.Id(), sUserName);
MAP1.put(sUserName, session);
}
//同⼀浏览器,同⼀⽤户(不做任何变动)
}else{
/
/未登录
Id())){
//同⼀浏览器,不同⽤户(不做任何变动)
}else{
//不同浏览器,不同⽤户(正常添加)
MAP2.Id(), sUserName);
MAP1.put(sUserName, session);
}
}
}
解释⼀下:这⾥使⽤username和userId效果⼀样,看你们怎么⽅便怎么⽤了,⽅法中的逻辑是根据上
⾯的图来编写的,⾸先判断⽤户是否登录了,因为MAP中保存了相关的session关联信息,所以可以通过这个来判断;由于此处只对不同浏览器相同⽤户进⾏处理,所以直接判断是否是同⼀个浏览器。⽅法的参数session是⽤户在当前浏览器登录时的信息,我们可以从MAP中得到之前保存过的相同⽤户的session信息,与之进⾏⽐较,⾥⾯的逻辑是:移除MAP中保存的之前的⽤户信息(对应的session此时未销毁),并给其session添加⼀个msg信息(后⾯⽤到,往下看),再添加新的⽤户信息。
上⾯的⽅法调⽤放在登录验证成功后,各⾃项⽬不同,但登录验证的类基本差不多:
SessionListener.userLogin(session, USERNAME);
(2)添加前端页⾯调⽤的⽅法
在登录验证的类中添加如下⽅法:
/*
* 判断⽤户是否重复登录
*/
@RequestMapping(value="/checkUserOnline")
@ResponseBody
public void checkUserOnline(HttpServletRequest request,HttpServletResponse response) throws IOException{
HttpSession Session();
PrintWriter out = Writer();
String msg = "";
Attribute("msg") != null){
msg = Attribute("msg").toString();
System.out.println(msg);
}
out.Attribute("msg"));
}
⽅法中获取之前添加到session中的msg,⽤来判断是否强制下线,继续。
(3)前端页⾯循环调⽤
选择⼀个页⾯,最好是所有页⾯都⽤到的,⽐如我⽤的index.jsp,如下:
<script type="text/javascript">
$(document).ready(function(){
setInterval("checkUserOnline()",5000); //每隔5秒判断⼀次
}
function checkUserOnline(){
var msg = "";
$.ajax({
type : "POST",
url : "checkUserOnline",
data : {},
async: false,
success : function(data){
msg = data;
}
});
if (msg == 'null' || msg == '' || msg == 'undefined'){
return;
}else{
//调⽤你的注销⽤户⽅法
var url="<%=path%>/logout.do";
$.get(url,function(data){});
}
}
</script>
js中调⽤setInterval⽅法,设置调⽤的⽅法和间隔时间,⽅法⾥通过ajax调⽤上⾯添加的类并返回msg,通过msg来判断是否调⽤注销⽅法(路径啥的⾃⼰注意,能调⽤到就ok)。
(4)注销
⼀般web项⽬登录进去后都会有个退出按钮,点击即返回到登录页,此时在⾥⾯添加⼀⾏代码,防⽌错误,可能会出现重新登录报session已被销毁的错误提⽰,但第⼆次便会成功,这⾥便是为了消除该错误:
Id());
好了,基本的设置完成了,启动项⽬,打开两个不同的浏览器,先登录⼀个⽤户,成功后,在另⼀个浏览器中登录相同的⽤户,登录成功后,会在控制台上打印出msg:
您的账号已在另⼀处登录!
此时,刷新第⼀个浏览器⽤户登录界⾯,便会发现已经退出跳转到登录页了,⼤功告成

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。