一个用户不能多人登陆,怎么解决 本帖最后由 darkhorse001 于 2009-07-23 13:58:18 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我只知道有个 单点登录, 怎么操作就不清楚了,其实可以考虑在数据库中加一个字段, 登录前要看这个值是否是已经登录的标识, 如果不是,登录成功后就将其设为已经登录,否则,就返回 false,不给登录 假如你数据库可以改的话,在数据库添加一个状态,假如不能改的话: 如果是Session就去判断Session是不是new 如果是Cokie的话就在Bean里添加一个状态值,用户监视当前用户状态 sql for update---行记录锁死。退出开锁。更新最后登陆时间字段。 单点登录这个问题很难解决的。如果在数据库中加字段进行区别,那么如楼上所说,用户非法退出怎么处理;如果是在session或者是Cokie的话那么在不同的机器上用一个用户名登录又该怎么处理等等,我目前也在考虑这个问题,不过还没有找到好的处理方法。 session监听器 。 package com.jzaccp.oa.grbg.sessionlistener; import javax.servlet.http.*; import javax.servlet.*; import java.util.*; public class onLineUser implements HttpSessionBindingListener { public onLineUser(){ } private Vector users=new Vector(); /** * 获取在线人数 * @return */ public int getCount(){ users.trimToSize(); return users.capacity(); } /** * 判断用户是否存在 * @param userName * @return */ public boolean existUser(String userName){ users.trimToSize(); boolean existUser=false; for (int i=0;i <users.capacity();i++ ) { if (userName.equals((String)users.get(i))) { existUser=true; break; } } return existUser; } /** * 删除用户 * @param userName * @return */ public boolean deleteUser(String userName) { users.trimToSize(); if(existUser(userName)){ int currUserIndex=-1; for(int i=0;i <users.capacity();i++){ if(userName.equals((String)users.get(i))){ currUserIndex=i; break; } } if (currUserIndex!=-1){ users.remove(currUserIndex); users.trimToSize(); return true; } } return false; } /** * 得到用户的列表 */ public Vector getOnLineUser() { return users; } /** * 植入session时调用的方法 * */ public void valueBound(HttpSessionBindingEvent e) { users.trimToSize(); if(!existUser(e.getName())){ users.add(e.getName()); System.out.print(e.getName()+"\t 登入到系统\t"+(new Date())); System.out.println(" 在线用户数为:"+getCount()); }else System.out.println(e.getName()+"已经存在"); } /** * * session过期或被关闭或退出调用的方法 */ public void valueUnbound(HttpSessionBindingEvent e) { users.trimToSize(); String userName=e.getName(); deleteUser(userName); System.out.print(userName+"\t 退出系统\t"+(new Date())); System.out.println(" 在线用户数为:"+getCount()); } } package Servlet;import javax.servlet.http.HttpSessionAttributeListener;import javax.servlet.http.HttpSessionBindingEvent;import javax.servlet.http.*;import java.util.*;public class SessionListener implements HttpSessionListener{ private static HashMap hUserName = new HashMap();//保存sessionID和username的映射 /**以下是实现HttpSessionListener中的方法**/ public void sessionCreated(HttpSessionEvent se){ } public void sessionDestroyed(HttpSessionEvent se){ hUserName.remove( se.getSession().getId() ); } /* * isAlreadyEnter-用于判断用户是否已经登录以及相应的处理方法 * @param sUserName String-登录的用户名称 * @return boolean-该用户是否已经登录过的标志 */ public static boolean isAlreadyEnter(HttpSession session,String sUserName){ boolean flag = false; if(hUserName.containsValue(sUserName)){//如果该用户已经登录过,则使上次登录的用户掉线(依据使用户名是否在hUserName中) flag = true; int i=0; //遍历原来的hUserName,删除原用户名对应的sessionID(即删除原来的sessionID和username) Iterator iter = hUserName.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); Object key = entry.getKey(); Object val = entry.getValue(); i++; if( ( (String)val ).equals(sUserName) ){ hUserName.remove(key); } } session.setAttribute("ii", i); hUserName.put( session.getId(),sUserName );//添加现在的sessionID和username System.out.println("hUserName = " + hUserName); } else{//如果该用户没登录过,直接添加现在的sessionID和username flag = false; hUserName.put( session.getId(),sUserName ); System.out.println("hUserName = " + hUserName); } return flag; } 纯理论,没有实践过!1,不要完全靠session来控制,session会有一个失效时间,这个时间不宜设的太短,否则正常工作会受影响。用监听事件的方法也是不可取的,事实上这个事件也会等到session过期的时候才会触发。2,可以采用隐藏桢的方式来检测用户的在线,这个时间可以设的比较短。比如5分钟。就像dev-club.com一样。在这个桢里得到用户名,当时的IP,以及访问时间。记录在application中。3,当另有用户来访问的时候,就判断在application的数据,如果已经有该用户的访问记录,就按IP和时间来判断,是否可以继续。比如说IP不同,但时间隔了很久了,就允许访问。4,你还可以再写一个后台进程来对application中的过期数据进行清理。5,对于使用代理或网关访问的用户判断可以这样,session对象有一个方法叫getId(),可以得到一个唯一的ID。即使使用同一IP来访问,这个ID也是不同的,可以加以区分。 给你说一下我用过的方法:1.在用户表里加一个字段,sessionid,在用户登录时创建的session的id值存入数据库,只需要在用户登录时修改这个值2.用一个过滤器,当用户请求过来时,检验一下当前请求的sessionid跟数据库中的是否一致,不一致则跳转到登录页面这个方法是不在登录时限制,而是把之前登录的用户踢下线,所以不存在意外登出时无法改变登录状态的情况,代价就是每个请求要比较一下sessionid,看你如何取舍了!仅供参考 监听器是可以 自动修改字段。。那很吊滴第一种情况 你可以在他关闭窗体滴时候去 修改数据库字段第二种情况就是 他直接把电源关掉(session监听30分钟用户没操作 ,就自动修改掉用户的状态)不过存在30分钟误差 ,,我也不知道怎么去掉。。//测试时间短一点 session.setMaxInactiveInterval(12);// Sesion有效时长,以秒为单位 我现在能想到的就是给工程加一个HttpSessionListener监听,但是这样做也不是很好,要是用户非正常退出,在session没过期前就登陆不进去了! http://topic.csdn.net/u/20081228/16/c89e1726-ec81-4a96-9bdf-478383578896.htmlhttp://mywork.javaeye.com/blog/66069 配个过滤器 路径设置 为/* 检查sessionId 的直 如果为null 则强行退出或者给提示 不停比对 1 个 登陆先恢复数据库sessionid null状态 再插入自己的 2在登陆时恢复默认值null 同时 也就相当于把1提下 去了 有点麻烦 没找到更好的 有别忘记告诉下啊 利用数据库中添加一字段来判断,是有漏洞的,假如用户非法退出,你的字段标识就改不回去了,下次就无法登陆了,上面有说可以捕获关闭事件,那么我问,如果我用任务管理器强制结束任务呢或者突然机器死掉了呢,类似的现象多了。 通过实践,我觉得可以用“踢人策略”,也就是最后一个登陆的主动剔除上一登陆者。具体做法如下: 在用户登陆的时候,把用户的帐号当Key,把产生的sessionID当value保存到全局变量中servletContext.setAttribute(userid,session.getId()); 然后配置过滤器(当每产生一次新的请求时,程序会先经过过滤器),在过滤器中对本次请求的sessionid进行判断(通过帐号获得保存的sesionid),看是否与全局变量中保存的sessionId一致,如果不一致,表明已经有用此帐户做新的一次登陆(每次登陆时会重新保存sessiondi,因为key(帐号)相同,所以value会被替换),那么上一用户将被强制退出(踢出)。 不给代码,只给正确的思路,这才真正的帮助你,别一提问题,就想要代码,思想是精髓。 用一个字段标识 用户是否已登录 然后在用session监视器 监视登录的session状态 来判断用户是否下线 用Session + 用户的方式是可以解决的。楼主只需要把设计目标改一下,就不用担心用户意外退出的问题了:对于同一个用户, 当它登录的时候,判断有没有已经登录的Session存在,如果有,就把先前登录的Session踢掉。 想完美的解决,估计很难,加字段还要session监控,意外事件不好把握。 使用spring的bean 单例缓存机制就可以实现 由于springFactroy 在整个服务器中正常情况下是唯一的,所以他的单例模式在一个服务器上也是唯一, 只要在登录的service上定义一个HashMap 用来保存用户 用户的登录名 , 当用户再次登陆时, 使用AOP方式,看看HashMap中是否存在着这个用户就可以解决这个问题了。 如果是多个服务器集成 , 使用Ehcache , 使得服务器的service对象同步 多个计算机集成,使用通信,使得内存同步 监听器,是不够的,最简单的一个列子,在有些操作系统浏览器下,左右frameset的sessionId都会不一样 可以用IP绑定 指定的ip可以登录 单用户单一登录,如果采用数据库字段纪录,当客户端出现异常,会死锁导致用户不便。而采用Session,如果没有过期,也会导致用户等待。用轮回查询,实在不是很好的方式。个人建议,完全可以采纳后一次登录踢出前一次用户,同时提醒被踢出的的用户。 首先每次登陆的时候把信息写入SESSION,然后存入一个静态变量,然后用一个过滤器,每次进入系统的时候判断新SESSION与原来存入变量里面值是否有相同,有相同则清空原有SESSION 加一个过滤器,然后像聊天室一样记录一个在线的用户列表及用户的sessionid,过滤器里判断是登录,登录了判断用户名是否已经在用户列表里。 这个方法不错,可以设定一个Application中数据的有效时间! 登录的时候将用户的ID放入Session中,因为用的ID是唯一的,所以当用户重新登录的时候就判断登录的用户的ID和Session 中已经存在的ID是否相同。重复登录的时候是不可以登录成功的。 写错了, 是放在Application中方案二。 用户登录后将用户的数据库中的状态改变,退出的时候再改回来。 package filter;import java.io.IOException;import java.util.HashMap;import java.util.Map;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import vo.UsersInfo;public class SsoFilter implements Filter { private static final String PARAM_PWD = "pwd"; // request发来的参数 private static final String PARAM_UID = "uid"; private static final String USERS_MAP = "userList"; // application中保存的用户列表 private static final String USER_INFO = "userInfo"; // session中保存用户时,作键 private static final String MSG = "msg"; // request中保存提示信息时,作键// private static final String MSG_USEING = "该账号正在使用中"; // 提示信息的值 private static final String MSG_NOTLOGIN = "您尚未登录"; private static final String MSG_BADLOGIN = "用户名或密码出错"; private static final String JSP_MAIN = "main.jsp"; // 重定向的页面 private static final String JSP_LOGIN = "login.jsp"; private HttpServletResponse response = null; // response private HttpServletRequest request = null; // request private HttpSession session = null; // session private ServletContext application = null; // application public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { // 初始化三个参数 request = (HttpServletRequest) arg0; response = (HttpServletResponse) arg1; session = request.getSession(); // 1.session已登录,则可以到任何页面 if (session.getAttribute(USER_INFO) != null) { arg2.doFilter(arg0, arg1); } else { // 2.1尝试登录 if (request.getRequestURI().indexOf(JSP_MAIN) != -1) { tryLogin(); } else { // 2.2尝试越权访问,前往登录页 request.setAttribute(MSG, MSG_NOTLOGIN); request.getRequestDispatcher(JSP_LOGIN).forward(arg0, arg1); } } } /** * 尝试登录 */ private void tryLogin() throws ServletException, IOException { String uid = request.getParameter(PARAM_UID); String pwd = request.getParameter(PARAM_PWD); // 直接访问主界面,视为未登录,返回登录页 if (uid == null || pwd == null || uid.equals("") || pwd.equals("")) { request.setAttribute(MSG, MSG_BADLOGIN); request.getRequestDispatcher(JSP_LOGIN).forward(request, response); return; } // 尝试登录 boolean b = uid.equals(pwd); if (b) { saveUserVariable(uid); request.getRequestDispatcher(JSP_MAIN).forward(request, response);// 登录成功,主界面 } else { request.setAttribute(MSG, MSG_BADLOGIN); // 用户名或密码出错 request.getRequestDispatcher(JSP_LOGIN).forward(request, response);// 登录失败,登录页 } } // 登录成功,两个步骤 // 1. session中保存用户身份 [key:USER_INFO, value:u] // 2. 更新application中的[在线用户列表] @SuppressWarnings("unchecked") private void saveUserVariable(String uid) { // 1.1 UsersInfo u = new UsersInfo(request.getRemoteAddr(), uid, session.getId()); session.setAttribute(USER_INFO, u); session.setMaxInactiveInterval(9000000); // 1.2 Map<String, HttpSession> map = application.getAttribute(USERS_MAP) == null ? new HashMap<String, HttpSession>() : (Map<String, HttpSession>) application.getAttribute(USERS_MAP); // 先判断是否有相同的人已经登陆了,如果有就把已经登陆的Session注销 if (map.size() > 0 && map.containsKey(uid)) { map.remove(uid).invalidate(); } map.put(uid, session); application.setAttribute(USERS_MAP, map); }// /**// * 是否已存在该用户的登录// * // * @return// */// @SuppressWarnings("unchecked")// private boolean isExist() {// // 表单中的用户名// String uid = request.getParameter(PARAM_UID);// // application中,用户名表列表// Set set = (Set) application.getAttribute(USERS_MAP) == null ? new HashSet()// : (Set) application.getAttribute(USERS_MAP);//// if (set.contains(uid)) {// request.setAttribute(MSG, MSG_USEING);// return true;// } else {// return false;// }// } /** * 初始化,赋值application */ public void init(FilterConfig config) throws ServletException { this.application = config.getServletContext(); } public void destroy() { }}同一时间只允许有一个浏览器使用该系统.当使用相同用户登录时,会把之前登录的挤下线 判断SESSION里是否有该用户就OK了。 我是楼猪,session失效,怎么实现自动跳转? 汗!我做过一次是用session判断 ,但是只能是在本机上面不允许相同账号的登录。。很汗 请问9楼的办法在JSP页面中怎么用呢 html js不运行问题 weblogic定时重启 Iframe 的使用问题 一些小问题。 关于SERVLET获得AJAX传递的参数后出现乱码 JAVAMAIL 怎么解决大文件上传问题 我的web程序要上传很多视频文件 都很大 请高手指点一点道路 关于javabean返回数组值和的在JSP页面显示的问题? jsp网站开发如何实现敏感词的屏蔽 我想在IIS+Resin环境下配置端口型虚拟主机 linux下firefox内嵌 GNOME-Mplayer的问题。 JDBC获得表的主键(自增)
假如不能改的话:
如果是Session就去判断Session是不是new
如果是Cokie的话就在Bean里添加一个状态值,用户监视当前用户状态
import javax.servlet.*;
import java.util.*; public class onLineUser implements HttpSessionBindingListener {
public onLineUser(){
} private Vector users=new Vector();
/**
* 获取在线人数
* @return
*/
public int getCount(){
users.trimToSize();
return users.capacity();
}
/**
* 判断用户是否存在
* @param userName
* @return
*/
public boolean existUser(String userName){
users.trimToSize();
boolean existUser=false;
for (int i=0;i <users.capacity();i++ )
{
if (userName.equals((String)users.get(i)))
{
existUser=true;
break;
}
}
return existUser;
}
/**
* 删除用户
* @param userName
* @return
*/
public boolean deleteUser(String userName) {
users.trimToSize();
if(existUser(userName)){
int currUserIndex=-1;
for(int i=0;i <users.capacity();i++){
if(userName.equals((String)users.get(i))){
currUserIndex=i;
break;
}
}
if (currUserIndex!=-1){
users.remove(currUserIndex);
users.trimToSize();
return true;
}
}
return false;
}
/**
* 得到用户的列表
*/
public Vector getOnLineUser()
{
return users;
}
/**
* 植入session时调用的方法
*
*/
public void valueBound(HttpSessionBindingEvent e) {
users.trimToSize();
if(!existUser(e.getName())){
users.add(e.getName());
System.out.print(e.getName()+"\t 登入到系统\t"+(new Date()));
System.out.println(" 在线用户数为:"+getCount());
}else
System.out.println(e.getName()+"已经存在");
}
/**
*
* session过期或被关闭或退出调用的方法
*/
public void valueUnbound(HttpSessionBindingEvent e) {
users.trimToSize();
String userName=e.getName();
deleteUser(userName);
System.out.print(userName+"\t 退出系统\t"+(new Date()));
System.out.println(" 在线用户数为:"+getCount());
} }
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.*;
import java.util.*;public class SessionListener implements HttpSessionListener
{
private static HashMap hUserName = new HashMap();//保存sessionID和username的映射
/**以下是实现HttpSessionListener中的方法**/
public void sessionCreated(HttpSessionEvent se){
}
public void sessionDestroyed(HttpSessionEvent se){
hUserName.remove( se.getSession().getId() );
}
/*
* isAlreadyEnter-用于判断用户是否已经登录以及相应的处理方法
* @param sUserName String-登录的用户名称
* @return boolean-该用户是否已经登录过的标志
*/
public static boolean isAlreadyEnter(HttpSession session,String sUserName){
boolean flag = false;
if(hUserName.containsValue(sUserName)){//如果该用户已经登录过,则使上次登录的用户掉线(依据使用户名是否在hUserName中)
flag = true;
int i=0;
//遍历原来的hUserName,删除原用户名对应的sessionID(即删除原来的sessionID和username)
Iterator iter = hUserName.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry)iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
i++;
if( ( (String)val ).equals(sUserName) ){
hUserName.remove(key);
}
}
session.setAttribute("ii", i);
hUserName.put( session.getId(),sUserName );//添加现在的sessionID和username
System.out.println("hUserName = " + hUserName);
}
else{//如果该用户没登录过,直接添加现在的sessionID和username
flag = false;
hUserName.put( session.getId(),sUserName );
System.out.println("hUserName = " + hUserName);
}
return flag;
}
1,不要完全靠session来控制,session会有一个失效时间,这个时间不宜设的太短,否则正常工作会受影响。用监听事件的方法也是不可取的,事实上这个事件也会等到session过期的时候才会触发。
2,可以采用隐藏桢的方式来检测用户的在线,这个时间可以设的比较短。比如5分钟。就像dev-club.com一样。在这个桢里得到用户名,当时的IP,以及访问时间。记录在application中。
3,当另有用户来访问的时候,就判断在application的数据,如果已经有该用户的访问记录,就按IP和时间来判断,是否可以继续。比如说IP不同,但时间隔了很久了,就允许访问。
4,你还可以再写一个后台进程来对application中的过期数据进行清理。
5,对于使用代理或网关访问的用户判断可以这样,session对象有一个方法叫getId(),可以得到一个唯一的ID。即使使用同一IP来访问,这个ID也是不同的,可以加以区分。
1.在用户表里加一个字段,sessionid,在用户登录时创建的session的id值存入数据库,只需要在用户登录时修改这个值
2.用一个过滤器,当用户请求过来时,检验一下当前请求的sessionid跟数据库中的是否一致,不一致则跳转到登录页面这个方法是不在登录时限制,而是把之前登录的用户踢下线,所以不存在意外登出时无法改变登录状态的情况,代价就是每个请求要比较一下sessionid,看你如何取舍了!仅供参考
第二种情况就是 他直接把电源关掉(session监听30分钟用户没操作 ,就自动修改掉用户的状态)
不过存在30分钟误差 ,,我也不知道怎么去掉。。//测试时间短一点
session.setMaxInactiveInterval(12);// Sesion有效时长,以秒为单位
http://topic.csdn.net/u/20081228/16/c89e1726-ec81-4a96-9bdf-478383578896.htmlhttp://mywork.javaeye.com/blog/66069
通过实践,我觉得可以用“踢人策略”,也就是最后一个登陆的主动剔除上一登陆者。具体做法如下:
在用户登陆的时候,把用户的帐号当Key,把产生的sessionID当value保存到全局变量中servletContext.setAttribute(userid,session.getId());
然后配置过滤器(当每产生一次新的请求时,程序会先经过过滤器),在过滤器中对本次请求的sessionid进行判断(通过帐号获得保存的sesionid),看是否与全局变量中保存的sessionId一致,如果不一致,表明已经有用此帐户做新的一次登陆(每次登陆时会重新保存sessiondi,因为key(帐号)相同,所以value会被替换),那么上一用户将被强制退出(踢出)。
不给代码,只给正确的思路,这才真正的帮助你,别一提问题,就想要代码,思想是精髓。
楼主只需要把设计目标改一下,就不用担心用户意外退出的问题了:
对于同一个用户, 当它登录的时候,判断有没有已经登录的Session存在,如果有,就把先前登录的Session踢掉。
由于springFactroy 在整个服务器中正常情况下是唯一的,所以他的单例模式在一个服务器上也是唯一,
只要在登录的service上定义一个HashMap 用来保存用户 用户的登录名 , 当用户再次登陆时,
使用AOP方式,看看HashMap中是否存在着这个用户就可以解决这个问题了。
如果是多个服务器集成 , 使用Ehcache , 使得服务器的service对象同步
多个计算机集成,使用通信,使得内存同步
过滤器里判断是登录,登录了判断用户名是否已经在用户列表里。
import java.util.HashMap;
import java.util.Map;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;import vo.UsersInfo;public class SsoFilter implements Filter {
private static final String PARAM_PWD = "pwd"; // request发来的参数
private static final String PARAM_UID = "uid";
private static final String USERS_MAP = "userList"; // application中保存的用户列表
private static final String USER_INFO = "userInfo"; // session中保存用户时,作键
private static final String MSG = "msg"; // request中保存提示信息时,作键
// private static final String MSG_USEING = "该账号正在使用中"; // 提示信息的值
private static final String MSG_NOTLOGIN = "您尚未登录";
private static final String MSG_BADLOGIN = "用户名或密码出错";
private static final String JSP_MAIN = "main.jsp"; // 重定向的页面
private static final String JSP_LOGIN = "login.jsp"; private HttpServletResponse response = null; // response
private HttpServletRequest request = null; // request
private HttpSession session = null; // session
private ServletContext application = null; // application public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
// 初始化三个参数
request = (HttpServletRequest) arg0;
response = (HttpServletResponse) arg1;
session = request.getSession(); // 1.session已登录,则可以到任何页面
if (session.getAttribute(USER_INFO) != null) {
arg2.doFilter(arg0, arg1);
} else {
// 2.1尝试登录
if (request.getRequestURI().indexOf(JSP_MAIN) != -1) {
tryLogin();
} else {
// 2.2尝试越权访问,前往登录页
request.setAttribute(MSG, MSG_NOTLOGIN);
request.getRequestDispatcher(JSP_LOGIN).forward(arg0, arg1);
}
}
} /**
* 尝试登录
*/
private void tryLogin() throws ServletException, IOException {
String uid = request.getParameter(PARAM_UID);
String pwd = request.getParameter(PARAM_PWD); // 直接访问主界面,视为未登录,返回登录页
if (uid == null || pwd == null || uid.equals("") || pwd.equals("")) {
request.setAttribute(MSG, MSG_BADLOGIN);
request.getRequestDispatcher(JSP_LOGIN).forward(request, response);
return;
} // 尝试登录
boolean b = uid.equals(pwd);
if (b) {
saveUserVariable(uid);
request.getRequestDispatcher(JSP_MAIN).forward(request, response);// 登录成功,主界面
} else {
request.setAttribute(MSG, MSG_BADLOGIN); // 用户名或密码出错
request.getRequestDispatcher(JSP_LOGIN).forward(request, response);// 登录失败,登录页
}
} // 登录成功,两个步骤
// 1. session中保存用户身份 [key:USER_INFO, value:u]
// 2. 更新application中的[在线用户列表]
@SuppressWarnings("unchecked")
private void saveUserVariable(String uid) {
// 1.1
UsersInfo u = new UsersInfo(request.getRemoteAddr(),
uid,
session.getId());
session.setAttribute(USER_INFO, u);
session.setMaxInactiveInterval(9000000); // 1.2
Map<String, HttpSession> map = application.getAttribute(USERS_MAP) == null
? new HashMap<String, HttpSession>()
: (Map<String, HttpSession>) application.getAttribute(USERS_MAP);
// 先判断是否有相同的人已经登陆了,如果有就把已经登陆的Session注销
if (map.size() > 0 && map.containsKey(uid)) {
map.remove(uid).invalidate();
}
map.put(uid, session);
application.setAttribute(USERS_MAP, map);
}// /**
// * 是否已存在该用户的登录
// *
// * @return
// */
// @SuppressWarnings("unchecked")
// private boolean isExist() {
// // 表单中的用户名
// String uid = request.getParameter(PARAM_UID);
// // application中,用户名表列表
// Set set = (Set) application.getAttribute(USERS_MAP) == null ? new HashSet()
// : (Set) application.getAttribute(USERS_MAP);
//
// if (set.contains(uid)) {
// request.setAttribute(MSG, MSG_USEING);
// return true;
// } else {
// return false;
// }
// } /**
* 初始化,赋值application
*/
public void init(FilterConfig config) throws ServletException {
this.application = config.getServletContext();
} public void destroy() {
}
}同一时间只允许有一个浏览器使用该系统.
当使用相同用户登录时,会把之前登录的挤下线
session失效,怎么实现自动跳转?