web项目中,同一时间同一帐号只能登录一个,新登录的将原来登录的挤下线,如何实现? 大概就是要像QQ一样的,同一账号在另一地点登录后,原先登录的就被迫下线,要怎么实现呢?希望大家给点建议! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 记录ip+账号+最后操作时间,组合成对象,装在application里如果出现了同样账号,不同IP,且操作时间间隔小于n秒的情况,把前一个的对象从这里抹去,下次再操作时就找不到对象,提示他自动登出了。不过这似乎可能会涉及到竞争资源的问题。 我之前做的权限判断都只是用session,假如用户登录成功后就request.getSession.setAttribute("username",username); 如何实现你说的将信息组合成对象放到application中呢? 你可以使用一个sessionMap<String,HttpSession> 使用用户ID作为key 在数据库写入一个字段lastlogintime.登陆的时候时间数据写入session..一段时间和数据库验证一下..如果不同自动登陆! 在applicationContext里面方一个Map,key为账户id,value为session。用户在登录的时候,应在session里存上该账户id,以做为该用户已经登录的标记,并在applicationContext的Map里面利用contains()方法来判断Map里面是否已经包含了此id的key,如果包含了,则把value(即session)取出,从这个session里面将记录的账户id删除,然后把新的session存进Map。这样原来的那个session里就没有账户id了,也就相当于原来登录的那个用于从登录状态转为了未登录状态。对于如果一个人在同一客户端使用同一账号登陆两次,这个我们不用考虑,因为一个客户端使用的是一个session,在登录的action里面我们本来就要判断session里是否已经含有账户id,如果有,上面那段操作无需执行,并且告知用户已经登录(即转到一个告知的页面,或使用其他途径)。难点在于这还没完,我们还要告诉原来登录的那个用户,“已经有人使用此账号在他处登录!”这么一个消息,这就有困难,没有request哪来responce啊?这个时候就要使用JS了,用JS写一个函数,该函数定时的向服务器发送请求(即使用了AJAX),并接受返回信息,如果接受到的返回信息文本是"false"或其他具有标识性的字符串,则表明有人在他处使用同一账号登录,即刻将浏览器跳转到其他页面,或弹出个警告框后再跳转。这个功能看起来似乎很简单,实现起来不是几行代码就能搞定的!不知道大家有没有更好的方法! 登陆的时候,把登陆信息的SESSION放到一个静态变量里面(比如HASHMAP),然后每次登陆,都和HASHMAP里面的值比较,如果相同,则把原来的SESSION清空,跳转到登陆页面。中间采用一个过滤器。 一个比较原始的方法,用IFRAME引入一个页面,用JS写一个定时刷面页面的方法.再把SESSION 和数据库交互的的方法写在页面里面,据结果考虑登陆或登出!当然如果你用struts等框架的话,就写在类里面通过js引发action.原理同上 session无法完成这样的事,客户登录后就有一个自己的session,应该存到application变量里面这样才能共享到。 http://www.lifeispig.cn/article.asp?id=127 这有一个用STRUTS2做的.不知道对你有帮助吗? 将已登录信息持久化或者放入application中,新请求用户访问的时候首先判断application中或者持久化(数据库)中有没有这个用户,如果有,清除即可。 很感谢各位提出的建议,对我启发很大!尤其是11楼的shanhenvgui说的很详细,还有gm66589160的iframe的方法,我也很有启发!我先试着弄弄,看看其他人还有什么看法么? 监听器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的监听类 ,获取用户的登出,登入,把登入的用户信息 通过 用户编号 和 sessionId 两个值放到HashMap 中,可以存到 application中,也可以放到静态变量里面。当用户登出的时候,就把登陆信息从 HashMap中移除。等用户登入的时候,把用户编号和sessionId 压入 HashMap中,那么已登录的用户的SessionId就会被覆盖掉。然后你做个过滤器,在过滤器里面,获取当前的Session信息,到HashMap里面获取 用户信息,然后比对SessionId是否一致,如果不一致,说明已经有新的登录了,就把这个Session删除,也就是踢出这丫的了。 这个问题很好解决其实,用户登录之后session中把用户名和sessionid保存起来,当再次登陆的时候判断这个用户凭是否存在以保存的列表中,如果不存在那么久登录,如果存在说明已经有人用这个账户登录,那么删除之前的sessionid,那么之前的就推出了 http://download.csdn.net/source/1525256我上传的一个JSP实例,里面有类似你说的功能,不过他只能不同用户不能重复登录,不能把之前那个登录得挤下去,只能是后面一个不能登录,使用监听器实现的 tomcat配置servlet jsp+mysql运行出现以下问题 高分紧急求助,tomcat下启动出问题 jsp怎么写javascript的服务端脚本呀? jsp 的最基本的分页面问题.帮帮忙 参数传递时能不能连带空格一起传递?? 请教ORACLE9I IAS中的中文字符问题。 (server.xml设置问题)如何指定多个web虚拟目录?(谢谢) 有没有人用jsp写过MIS系统? 如何在spring mvc hibernate中使用jxl将数据库内容下载导入excel 如何获取JSP本页面表单元素的值 关于request.getParameter()得值的问题
如果出现了同样账号,不同IP,且操作时间间隔小于n秒的情况,把前一个的对象从这里抹去,下次再操作时就找不到对象,提示他自动登出了。
不过这似乎可能会涉及到竞争资源的问题。
request.getSession.setAttribute("username",username);
如何实现你说的将信息组合成对象放到application中呢?
你可以使用一个sessionMap<String,HttpSession> 使用用户ID作为key
用户在登录的时候,应在session里存上该账户id,以做为该用户已经登录的标记,并在applicationContext的Map里面利用contains()方法来判断Map里面是否已经包含了此id的key,如果包含了,则把value(即session)取出,从这个session里面将记录的账户id删除,然后把新的session存进Map。
这样原来的那个session里就没有账户id了,也就相当于原来登录的那个用于从登录状态转为了未登录状态。对于如果一个人在同一客户端使用同一账号登陆两次,这个我们不用考虑,因为一个客户端使用的是一个session,在登录的action里面我们本来就要判断session里是否已经含有账户id,如果有,上面那段操作无需执行,并且告知用户已经登录(即转到一个告知的页面,或使用其他途径)。难点在于这还没完,我们还要告诉原来登录的那个用户,“已经有人使用此账号在他处登录!”这么一个消息,这就有困难,没有request哪来responce啊?这个时候就要使用JS了,用JS写一个函数,该函数定时的向服务器发送请求(即使用了AJAX),并接受返回信息,如果接受到的返回信息文本是"false"或其他具有标识性的字符串,则表明有人在他处使用同一账号登录,即刻将浏览器跳转到其他页面,或弹出个警告框后再跳转。这个功能看起来似乎很简单,实现起来不是几行代码就能搞定的!
不知道大家有没有更好的方法!
当然如果你用struts等框架的话,就写在类里面通过js引发action.原理同上
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() {
}
}