当前位置: 技术问答>java相关
请教一个登录问题,很简单的,我急用,50分,一定给分!!!
来源: 互联网 发布时间:2015-03-22
本文导语: 请问各位大侠,当一个用户登录后,另一个用户不能再用此用户名登录系统,请问如何实现这一功能,有没有做过的,能不能提供点原代码,谢谢了! | 建立一个登录登记表(signin表) 里面有...
请问各位大侠,当一个用户登录后,另一个用户不能再用此用户名登录系统,请问如何实现这一功能,有没有做过的,能不能提供点原代码,谢谢了!
|
建立一个登录登记表(signin表)
里面有用户名(username),客户端IP地址(ipadd)。
用户登录时先查询signin表中是不是有用户的IP地址,如果没有在signin表中插入一条纪录。
然后设置一个session,用户访问页面时都监测session是不是有效,没有效的话就从signin表中删除ipadd字段和用户IP地址相同的记录。
这样可以实现重复登录。
但是这样做有缺点,就是如果多个用户都通过统一台防火墙或代理服务器上网就会有IP地址重复。
所以我的办法也不好。
如果哪位高手有解决的办法,请指教。
里面有用户名(username),客户端IP地址(ipadd)。
用户登录时先查询signin表中是不是有用户的IP地址,如果没有在signin表中插入一条纪录。
然后设置一个session,用户访问页面时都监测session是不是有效,没有效的话就从signin表中删除ipadd字段和用户IP地址相同的记录。
这样可以实现重复登录。
但是这样做有缺点,就是如果多个用户都通过统一台防火墙或代理服务器上网就会有IP地址重复。
所以我的办法也不好。
如果哪位高手有解决的办法,请指教。
|
利用servlet是线程的特性,使用共享数据区(一般使用只有唯一实例的对象)存放已登陆用户和登陆时的sessionID,用一个线程来监测登陆用户是否退出。
|
在数据库里边设置一个标志,当用户登陆的时候把标志置位。
你在登陆的时候查看一下这个标志,如果没有置位,就让他登陆,有的话就给他踢了!
在下线的时候你可以给标志复位。
检查下线用线程,只要用户登陆就起一个,一段时间去查看他掉了么,掉了就复位。
还有一个方法,(前提是用户少),你可以一次读取所有的用户存放到session里边。当一个用户登陆进来就把他从session中去掉,所有的用户必须是session里的。(session可以存放ArrayList,取出来的时候必须进行强制转换)。这样行么?检查ip太累了。
你在登陆的时候查看一下这个标志,如果没有置位,就让他登陆,有的话就给他踢了!
在下线的时候你可以给标志复位。
检查下线用线程,只要用户登陆就起一个,一段时间去查看他掉了么,掉了就复位。
还有一个方法,(前提是用户少),你可以一次读取所有的用户存放到session里边。当一个用户登陆进来就把他从session中去掉,所有的用户必须是session里的。(session可以存放ArrayList,取出来的时候必须进行强制转换)。这样行么?检查ip太累了。
|
有个最典型的例子
用连接池和Hash表的用户登陆人证
登陆的bean是application
维护一个hash表,键就是userName
值是一个类,里面有个isLogin的属性,记录用户是否已经登陆,
还有其他的属性,如登陆时间,是否超时等
大概就是这样的思路,你可以到网上找到有关的例子
用连接池和Hash表的用户登陆人证
登陆的bean是application
维护一个hash表,键就是userName
值是一个类,里面有个isLogin的属性,记录用户是否已经登陆,
还有其他的属性,如登陆时间,是否超时等
大概就是这样的思路,你可以到网上找到有关的例子
|
to xsulver:
如果客户端的浏览器用完之后就退出了,但是没有做logout操作,那下次岂不是就登录不进来了吗?
看了各位的答案,只有whd11808涉及了这个问题的难点:在数据库里或者javabean里设标志谁都能想得到,但是怎么才能保证用户退出的时候把这个标识复位呢?要知道用户用的是浏览器,它可以直接alt+f4呀!
whd11808提供了线程的方法,不过要是用户很多怎么办?1000个用户代表着有1000个线程时不时执行一次,开销很大的呀!
如果客户端的浏览器用完之后就退出了,但是没有做logout操作,那下次岂不是就登录不进来了吗?
看了各位的答案,只有whd11808涉及了这个问题的难点:在数据库里或者javabean里设标志谁都能想得到,但是怎么才能保证用户退出的时候把这个标识复位呢?要知道用户用的是浏览器,它可以直接alt+f4呀!
whd11808提供了线程的方法,不过要是用户很多怎么办?1000个用户代表着有1000个线程时不时执行一次,开销很大的呀!
|
呵呵!看来大家挺看好我的方法啊!呵呵,下边是我以前做的,网络qq的一部分,大家看看吧。
package easytalk;
import java.util.*;
/**
*存储在线用户信息的JavaBeans
*自动将久未连线的用户踢出列表
*/
public class userList
{
//所有的用户名
private HashMap userList;
//用户聊天中两次输入的最大间隔
//大于此间隔时需要重新登录
private int activeTimeLimit = 60000;
/**
*构造函数,不包含任何参数
*/
public userList()
{
userList = new HashMap();
}
/**
*取得一个包含当前用户信息的迭代器
*@return 包含当前用户名信息的Iterator类型对象
*@see java.util.Iterator
*/
public Iterator getUserList()
{
//将超时用户踢出列表
removeOverdue();
//构建一个迭代嚣并返回
HashMap returnUserList = new HashMap(userList);
Set returnUserSet = returnUserList.keySet();
Iterator returnUserIterator = returnUserSet.iterator();
return returnUserIterator;
}
/**
*更新原有用户
*@param userName 需要加入的用户名
*@param id 需要加入的用户标识
*/
public void updateUser(String id,String userName,String userPic)
{
//获得当前时间
Vector userInfo=new Vector(3);
Date dateTimeNow = new Date();
long longTimeNow = dateTimeNow.getTime();
Long longOTimeNow = new Long(longTimeNow);
userInfo.add(id);
userInfo.add(userPic);
userInfo.add(longOTimeNow);
//将用户最近一次发出的时间存储起来
userList.put(userName,userInfo);
}
/**
*监测用户是否在用户列表中
*/
public boolean isUserOnLine(String userName)
{
//将超时用户踢出列表
removeOverdue();
return userList.containsKey(userName);
}
/**
*将用户加入到此用户列表中
*@param userName 需要加入的用户名
*/
public void addUser(String id,String userName,String userPic)
{
//获得当前时间
Vector userInfo=new Vector(3);
Date dateTimeNow = new Date();
long longTimeNow = dateTimeNow.getTime();
Long longOTimeNow = new Long(longTimeNow);
userInfo.add(id);
userInfo.add(userPic);
userInfo.add(longOTimeNow);
//将用户最近一次发出的时间存储起来
userList.put(userName,userInfo);
}
/*将超时用户踢出列表
*按照方法setActiveTimeLimit()设定的时间间隔
*/
public void removeOverdue()
{
//为了防止进行枚举时有其他用户访问原有的HashMap
//造成java.util.ConcurrentModificationException异常
//这里建立一个新的HashMap对象来进行枚举
HashMap temp = new HashMap(userList);
Set nameSet = temp.keySet();
Iterator nameIterator = nameSet.iterator();
//将在线用户列表中的用户数据取出
while (nameIterator.hasNext())
{
//获得用户最近一次发出的请求的时间
String name = (String) (nameIterator.next());
Vector returnVector =(Vector) userList.get(name);
Long longOLastAccessTime = (Long)returnVector.get(2);
long longLastAccessTime = longOLastAccessTime.longValue();
//获得当前时间
Date dateTimeNow = new Date();
long longTimeNow = dateTimeNow.getTime();
//检查用户是否超时
//如果用户超时就将用户踢出用户列表
//其中activeTimeLimit是预先定义的超时时限
if (longTimeNow - longLastAccessTime > activeTimeLimit)
{
userList.remove(name);
}
}
}
/**
*得到用户再次操作的最大允许时间间隔
*@return 最大允许时间间隔,以毫秒计算
*/
public int getActiveTimeLimit()
{
return activeTimeLimit;
}
/**
*设定用户两次操作的最大允许时间间隔
*@param activeTimeLimit 需要设定的最大允许时间间隔,以毫秒计算
*/
public void setActiveTimeLimit(int activeTimeLimit)
{
this.activeTimeLimit = activeTimeLimit;
}
}
package easytalk;
import java.util.*;
/**
*存储在线用户信息的JavaBeans
*自动将久未连线的用户踢出列表
*/
public class userList
{
//所有的用户名
private HashMap userList;
//用户聊天中两次输入的最大间隔
//大于此间隔时需要重新登录
private int activeTimeLimit = 60000;
/**
*构造函数,不包含任何参数
*/
public userList()
{
userList = new HashMap();
}
/**
*取得一个包含当前用户信息的迭代器
*@return 包含当前用户名信息的Iterator类型对象
*@see java.util.Iterator
*/
public Iterator getUserList()
{
//将超时用户踢出列表
removeOverdue();
//构建一个迭代嚣并返回
HashMap returnUserList = new HashMap(userList);
Set returnUserSet = returnUserList.keySet();
Iterator returnUserIterator = returnUserSet.iterator();
return returnUserIterator;
}
/**
*更新原有用户
*@param userName 需要加入的用户名
*@param id 需要加入的用户标识
*/
public void updateUser(String id,String userName,String userPic)
{
//获得当前时间
Vector userInfo=new Vector(3);
Date dateTimeNow = new Date();
long longTimeNow = dateTimeNow.getTime();
Long longOTimeNow = new Long(longTimeNow);
userInfo.add(id);
userInfo.add(userPic);
userInfo.add(longOTimeNow);
//将用户最近一次发出的时间存储起来
userList.put(userName,userInfo);
}
/**
*监测用户是否在用户列表中
*/
public boolean isUserOnLine(String userName)
{
//将超时用户踢出列表
removeOverdue();
return userList.containsKey(userName);
}
/**
*将用户加入到此用户列表中
*@param userName 需要加入的用户名
*/
public void addUser(String id,String userName,String userPic)
{
//获得当前时间
Vector userInfo=new Vector(3);
Date dateTimeNow = new Date();
long longTimeNow = dateTimeNow.getTime();
Long longOTimeNow = new Long(longTimeNow);
userInfo.add(id);
userInfo.add(userPic);
userInfo.add(longOTimeNow);
//将用户最近一次发出的时间存储起来
userList.put(userName,userInfo);
}
/*将超时用户踢出列表
*按照方法setActiveTimeLimit()设定的时间间隔
*/
public void removeOverdue()
{
//为了防止进行枚举时有其他用户访问原有的HashMap
//造成java.util.ConcurrentModificationException异常
//这里建立一个新的HashMap对象来进行枚举
HashMap temp = new HashMap(userList);
Set nameSet = temp.keySet();
Iterator nameIterator = nameSet.iterator();
//将在线用户列表中的用户数据取出
while (nameIterator.hasNext())
{
//获得用户最近一次发出的请求的时间
String name = (String) (nameIterator.next());
Vector returnVector =(Vector) userList.get(name);
Long longOLastAccessTime = (Long)returnVector.get(2);
long longLastAccessTime = longOLastAccessTime.longValue();
//获得当前时间
Date dateTimeNow = new Date();
long longTimeNow = dateTimeNow.getTime();
//检查用户是否超时
//如果用户超时就将用户踢出用户列表
//其中activeTimeLimit是预先定义的超时时限
if (longTimeNow - longLastAccessTime > activeTimeLimit)
{
userList.remove(name);
}
}
}
/**
*得到用户再次操作的最大允许时间间隔
*@return 最大允许时间间隔,以毫秒计算
*/
public int getActiveTimeLimit()
{
return activeTimeLimit;
}
/**
*设定用户两次操作的最大允许时间间隔
*@param activeTimeLimit 需要设定的最大允许时间间隔,以毫秒计算
*/
public void setActiveTimeLimit(int activeTimeLimit)
{
this.activeTimeLimit = activeTimeLimit;
}
}
|
在数据库中设置一个标志.
|
或在aplication中设置标志