一个用户只能有一处在线,若在其它地方再登录则把上一个登录的给踢了
俺开始的想法:把用户登录的session都存起来,然后新上一个用户就找它是否登录,找到则取出将该session杀掉,此时再给这个新登的用户建立session
此种方法被上面否掉说是session作废只能从那个客户端发送请求,俺不了解session工作的细节,搞不清楚是怎么回事,看大家有没有什么其它的办法,谢谢先!
另:还想过让用户关闭页面时发送一个请求注掉session,这个希望大家就不要提了.
俺开始的想法:把用户登录的session都存起来,然后新上一个用户就找它是否登录,找到则取出将该session杀掉,此时再给这个新登的用户建立session
此种方法被上面否掉说是session作废只能从那个客户端发送请求,俺不了解session工作的细节,搞不清楚是怎么回事,看大家有没有什么其它的办法,谢谢先!
另:还想过让用户关闭页面时发送一个请求注掉session,这个希望大家就不要提了.
用户ID , 登陆ID(自增长),其它信息....
(1)每一个用户作“登陆操作”时,将这个表中插入一个字段,记录用户的ID,然后把这个“登陆ID”保存到Session中。
(2)之后,用户作任何操作以前,都要到“登陆信息表”中按“用户ID”来查询“登陆ID”并取最大值。
(3)看看这个数值是不是比当前Session中保存的“登陆ID”的值大,如果有个更大的值则证明这个用户重复登陆。于是把当前页面强转到“登陆页面”。OK这个操作可以放到Filter里来写,节省代码量。
并且还设置了超时时间,以及浏览器关闭的时候自动注销session
我有个思路每个用户登陆的时候 把sessionID和用户ID捆绑保存《如到一个静态LIST里面》起来,,,当一个新用户登陆验证通过的时候 查询 LIST 里面这个用户是不是已经登陆了 如果登陆了就删除以前的 sessionID 换成现在的 sessionID,而先登陆的那个用户在浏览页面的时候都加个判断(或者在要进行数据库操作的时候判断),这个 用户的sessionID 是否还保存在 静态LIST里面 如果没有 就提醒这个用户重新重新登陆并注销这个用户的 session.invalidate();
就是这个。
判断 静态LIST 这个回话ID没有的时候 就让他的 放资料的回话失效那就不能进行操作了也就达到了我们的目的
session.setAttribute("USER", 用户ID);然后你在任何页面需要用户ID的时候都调用
String UserID=session.getAttribute("USER");知道ID你们才能进行数据库修改操作对不我不知道你们把象用户ID这些东西放到那去。。但总不会每次访问个新页面要别人重新登陆把。。按我上面的思路
但静态 LIST 没有这个会话的ID的时候就 session.invalidate(); 那他访问到需要 调用
String UserID=session.getAttribute("USER"); 时候这个获取不到值,,就无法操作还有什么不对了。
你的想法是对的,他们否定的原因估计是他们觉得实现不了,我们公司就是这样做的
并且还设置了超时时间,以及浏览器关闭的时候自动注销session
你是说我将第一个用户的session取出再session.invalidate();是可以的?手头事太多,没试过.浏览器关闭自动注销估计也是捕捉窗口关闭事件吧,可是你们怎么区分刷新与关闭的呢?我有办法区分,但是这样又不能捕捉到点文件中的关闭了.to qczl1224(倾请一世) :
俺也觉得思路是可行的,只是好像在做动作前要判断,而且可能还要监听session,不然自己注销的用户不会从列表中去掉
晕没有找到就+呀。。找到了就替换会话ID
我们公司现在主要是在数据库中查询,大数据量的时候静态list的效率也不高
俺也觉得思路是可行的,只是好像在做动作前要判断,而且可能还要监听session,不然自己注销的用户不会从列表中去掉去不去掉无所谓。。自己注销的话 放String UserID=session.getAttribute("USER");
会失效,即使他象操作都没法操作。。 你在每个需要登陆才能浏览的页面是不是要判断 String UserID=session.getAttribute("USER");获得的值是不是空了,如果是空就代表没有登陆呀,,,并且第二次登陆会消掉第一此登陆用户的 sessionID的
我们公司现在主要是在数据库中查询,大数据量的时候静态list的效率也不高晕你有几百W用户同时登陆吗。。静态list 放几千个 就 sessionID 和用户ID会影响性能吗??????????sessionID 24位把 用户ID 20位以内把1000个用户同时在线 静态list才4K.....
想问一个比较弱的问题,存sessionID用什么办法得到session?列个具体的
第一次登陆一般都要查询数据库,数据库中也会有相应的字段描述,
我们公司现在主要是在数据库中查询,大数据量的时候静态list的效率也不高晕你有几百W用户同时登陆吗。。静态list 放几千个 就 sessionID 和用户ID会影响性能吗??????????sessionID 24位把 用户ID 20位以内把1000个用户同时在线 静态list才4K.....
哥哥息怒,我只是说效率也不高,并没说他影响性能阿,我只是觉得我既要维护数据库的数据,又要去维护静态表,这样对我来说复杂性增大了,所以(只是我个人看法)我会在数据库中维护。我们银行系统的,所以在线用户有可能很大
想问一个比较弱的问题,存sessionID用什么办法得到session?列个具体的sessionID不用我说了 HttpSession session = request.getSession(true);
登陆页面从请求创建一个session
然后你可以用 String UserID=session.getAttribute("USER");
当然你还可以放对象里面 HashMap map = new HashMap();
map.put("userID", resultBean.getUserID()+"");
map.put("nickName", resultBean.getNickName());
map.put("membership", resultBean.getMembership()+"");
map.put("passCard", resultBean.getPassCard());
map.put("isforbid", resultBean.getIsforbid());
map.put("authorType", resultBean.getAuthorType());
map.put("requeseUrl", requeseUrl);
session.setAttribute("USER", map);
那个客户端执行到 session.invalidate();都会消除他 这个sessionID 创建的的所有session 就是假如 一个用户登陆以后 我把他的sessionID 和UserID放到 LIST里面 (先判断LIST有没有有的话就删除以前的再添加现在的。。)登陆之后 创建了这个 String UserID=session.getAttribute("USER"); 任何需要登陆的页面我都先判断 String UserID=session.getAttribute("USER");获得的值是否为空,为空就跳到登陆页面登陆,不为空就判断会话ID有没存到 LIST里面 有的话就继续,,没有就 session.invalidate(); 那为这个用户创建的这个String UserID=session.getAttribute("USER"); 没有了,
明白了,其实你绕开我提的那个问题,不过这样挺不错的!
俺的思路没转过来,以为存sessionId是为了取得session对象,然后注.俺的思路是一个主动找到,而兄弟的想法是等被踢的人上来时再让有他自己那里注掉,谢谢了!
这个帖子最多开到明天早上,一定给分结贴!
感谢所有帮忙的!
{
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException
{
COPWebController controller = null;
COPEventResult_Object result = null;
String strMapping = null;
String strError = null;
int i = 0;
try
{
HttpSession session = request.getSession(true);
UserForm formbean = (UserForm) form;
UserBean vbean = formbean.getUserBean();//获得用户登陆的帐号密码
String requeseUrl=request.getParameter("requeseUrl");//获取请求页面的路径
System.out.println("************************"+requeseUrl);
controller = getController(request); result = (COPEventResult_Object) controller.handleEvent(new UserCommand(passCard,"login"));//通过用户名查询一些资料
UserBean resultBean = (UserBean) result.getValue();
if (resultBean == null)
{
strError = "此用户不存在,请重新注册!";
i++;
strMapping = "fault";
}
else if (!resultBean.getPassword().trim().equals(vbean.getPassword().trim()))
{
strError = "用户密码不正确,请重新输入!";
i++;
strMapping = "fault"; }if (strMapping == null)
{
strMapping = "list";
HashMap map = new HashMap();
map.put("userID", resultBean.getUserID()+"");
map.put("nickName", resultBean.getNickName()); session.setAttribute("USER", map);//把用户ID和昵称放到会话里面
CounterLisenter.isAlreadyEnter(session,passCard);//方法自己写把这个方法把 会话和用户ID传过去执行 没有就加有的话就删了加
}else
{
session.setAttribute(passCard, String.valueOf(i));
}
session.setAttribute("LOGIN_MSG", strError);
if(requeseUrl!=null)
{
strMapping="requeseUrl";
}
return new ActionForward(mapping.findForward(strMapping).getPath(), true);
}
catch (Exception e)
{
e.printStackTrace();
}
return new ActionForward(mapping.findForward("fault").getPath(), true);
}
}session.setAttribute("USER", map);//把用户ID和昵称放到会话里面 页面可以这样调用 HashMap cmap = (HashMap) session.getAttribute("USER");
String userID ="";
String nickName="";
if(cmap!=null){userID = cmap.get("userID").toString(); nickName = cmap.get("nickName").toString();}CounterLisenter.isAlreadyEnter(session,passCard);//方法自己写把这个方法把 会话和用户ID传过去执行 没有就加有的话就删了加
明白了,其实你绕开我提的那个问题,不过这样挺不错的!
俺的思路没转过来,以为存sessionId是为了取得session对象,然后注.汗 这是他不用正常方法推出的,,正常推出的时候你可以写代码要她消掉呀一般退出的时候 session.invalidate(); 是要用到的,,,
嗯,再次感谢!
这样是针对用户的非正常退出,很多人都不喜欢点注销,嘿嘿.
辛苦辛苦,俺没要代码,俺那时说要个具体的是说如果有通过sesssionId取到那个session的方法的话俺要一个方法,这里没有丝毫不尊重qczl1224的劳动的意思,
再说一句,谢谢啊!
我想到了解决的办法!
楼上几位说的有点道理,但是如果用户是第一次登陆呢?你的list列表里一定没有这个用户的SessionId,他岂不是永远都无法登陆了?
我想到了解决的办法! 数据库中一般会纪录用户是否已登陆,用那个东西可以判断
楼上几位说的有点道理,但是如果用户是第一次登陆呢?你的list列表里一定没有这个用户的SessionId,他岂不是永远都无法登陆了?我想到了解决的办法!
汗不知道你到底要怎么样。不管那一次登陆都是 判断 list列表 没有就添加就是了,有就删除以前的再添加现在的。。还要怎么样想解决办法。这个本来就没有你说的 无法登陆问题难道你是想说 服务器刚开的时候 list列表 列表为空的时候无法判断。。汗呀。。list列表为空你直接返回 判断这个用户没有登陆就是(不知道你怎么学的这个是比较基本的判断。。)
当用户登陆时先检查列表中是否有此sessionID,userID没有就建一个sessionIsValidate设为true.如果有就判断sessionIsValidate是否为true,为true,响应请求.不为true,看下面.
另一个用户登陆,检查发现没有此sessionID,但是有相同的userID,可知是相同帐号登陆两次,想把第一个用户踢掉,找到列表中已存在的那个userID,将sessionIsValidate设为false,并将此用户的sessionID,userID,sessionIsValidate(设为true).
当先登陆的用户再次发出请求时,检查sessionID发现有,检查sessionIsValidate为false,调用session.invalidate(); 并把列表中对应记录删除,提示他重新登陆!不知道这样每次用户发出请求时都检查列表,开销会不会很大.harston(顽石)
数据库中一般会纪录用户是否已登陆,用那个东西可以判断很有用,当用户第一次登陆时,判断一下登陆状态,没登陆的直接存入列表,让用户登陆,不用检查列表!
有就删除,晕哦,当A(代号)登陆后,你给A一个session,并保存在列表中,当B用相同帐号登陆后,你把A从列表中删除,当A再次发出请求,你用String username = session.getAttribute("username");取值,A还是能取到的,因为你只是把A从列表中删除了,A的session由容器管理,只要没有过期,还是存在的.服务器仍然继续响应A.
当A再次发出请求时,如果你先判断列表中是否有此userID,此时应该是有的,因为B已经登陆了,再删除,重建,B从列表中被删除,A继续,B再请求,A被删除,B继续,有意义吗?A和B都在继续!
A登陆了 有 sessionID 和他的 并创建了放个人资料的session,
B登陆了
A再访问页面判断到 sessionID 已经没有了 执行 session.invalidate(); 那他的个人资料没有了。还怎么再访问页面,你告诉我可能你理解错在 以为这个 (放个人资料的session是自动创建) 是你编代码创建的,以便有些页面随时调用!当 session.invalidate(); 时候那些需要调用这个用户资料的 session无法调用你说还怎么继续。
1. norwolfli(烟灰) ( ) 信誉:100 2006-06-05 15:49:00 得分: 0
session.invalidate(); 这句话,只能销毁当前用户的session,也就是谁请求就销毁谁,而不能去销毁已经登陆用户的session
当用户第一次登录时把它的session对象存起来,第二个用户登录上后取出第一个的session对象,用session.invalidate(),可以将第一个用户的session注掉即踢了吗?
2. harston(顽石)
恩,这个过程是被动的。
还有,session.getId()获取的值在不同的窗口之间是不同的,所以,你最好自己设置一个信息来判断。 session.getId()得到的id值是会变的?同一个用户用此方法可能得到多个不同的值那也就是说此id值不能用来验证是不是同一个用户的session了?
要是能取到问题就简单了.
第二个问题是:最好不用id判断,你自己定义一个userId什么的。
csdn上,你开一个窗口登陆,左边会显示你的名字。如果你再开一个窗口,输入http://community.csdn.net/你会发现左边没有你的名字,估计是因为用sessionId判断的原因
[原创]利用HttpModuler实现WEB程序同一时间只让一个用户实例登陆(修改)
1. norwolfli(烟灰) ( ) 信誉:100 2006-06-05 15:49:00 得分: 0
session.invalidate(); 这句话,只能销毁当前用户的session,也就是谁请求就销毁谁,而不能去销毁已经登陆用户的session
当用户第一次登录时把它的session对象存起来,第二个用户登录上后取出第一个的session对象,用session.invalidate(),可以将第一个用户的session注掉即踢了吗?倒。。,第二个用户登录和只是把放到静态LIST里面的第一个用户的 sessionID删掉,他无权注销第一用户创建的会话!
第一个用户在第二用户登陆后当他打开或刷新网页触发检测的时候 ,检测 静态LIST里面 他的sessionID是否存在?不存在 他就执行 session.invalidate()(也就是他第一个用户自己注销他自己的 会话 !) <%@ page import="java.util.*"%>
<% HashMap isUser = (HashMap)session.getAttribute("USER");
if (isUser == null)
{
response.sendRedirect("../syspagejsp/loginFaul.jsp");//返回登陆
}else(判断sessionID是不存在LIST)//不存在执行session.invalidate();{
session.invalidate();
}
存在就验证通过
%>
我明白你的流程,开始我就说你绕过了这个问题嘛,我是说你的解决方案不会遇到要在第二个用户那儿注第一个用户session的问题.倒。。,第二个用户登录和只是把放到静态LIST里面的第一个用户的 sessionID删掉,他无权注销第一用户创建的会话! 这里是问题1的答案,即使取到了用户一的session对象也不能注.
。。当你浏览一个网页的时候 服务器和浏览器就会建立一个sessionID(不管力静态网站还是动态网站) !
别的用户访问的时候会建立另一个 sessionID
是不通用的 你打开二个浏览器,同一个网站一个浏览器登陆,一个浏览器不登陆,只要登陆的时候没有记载 COOKIE 那那个没登陆的页面是不可能访问需要登陆才能访问的页面的,,,原因就是 服务器创建的会话是根据 sessionID 创建的 不同的 sessionID 不可以访问 其他sessionID 创建的服务器会话!
看来JSP还是不如ASP.net,这么简单的问题,在JSP下如此难
是呀,还是ASP.net简单 1个月都学的查不多。JSP要搞半年差不多。。不过ASP.net技术简单所以没挑战性,要想提高能力的话还是要学技术性比较强,,, 就象你用
Dreamweaver 编网页没有人家用 文本文档编网页编的好一样,用文本编技术要好,并且不会有垃圾代码。。Dreamweaver 编的话垃圾代码有多(不必要的标签,或不不要多次套用的标签等)等等
我的意思是说,思路是可以借鉴的吗?
像我在和别的公司的Java的程序员作接口时,还得我来写Java的相应代码:
如:[原创]Java实现PKCS7填充的DES加密(修订版)(http://evlon.cnblogs.com/archive/2006/04/14/374971.aspx)Java下X86机,Bytes和Int的转换 (http://evlon.cnblogs.com/archive/2006/04/22/381947.html)
如果运行不起来是自己代码问题,
和服务器无关,。不能让服务器迁就代码,而是让代码适应任何服务器
要是能取到问题就简单了.再次犯了想当然的错误,试验发现,取到了其它人的session,也不让销毁.对不起了!!我刚才试了一下,取到另一个session是可以的,里面的值也能取到,但就是不能销毁!为什么不知道,估计是session.invalidate()先判断执行这个方法的sessionID是多少,如果不是标识这个session的,就抛异常!
如果要看思路的就访问这页,如果要代码明天公布一个监听功能完整的非完整(未测试提示各种消息的session)的SessionListener.
很简单的东西讨论这么长,也真厉害了。一个监听器加几个全局静态变量就搞定了。public class SessionListener extends HttpServlet implements HttpSessionListener {
public static java.util.HashMap sessionl= new java.util.HashMap();
//Notification that a session was created
public void sessionCreated(HttpSessionEvent se) {
System.out.println("新创建 sessionid is "+se.getSession().getId());
//把session的引用放到一个全局静态变量里
sessionl.put(se.getSession().getId(),se.getSession());
}//Notification that a session was invalidated
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("被释放的 sessionid is "+se.getSession().getId());
//把session的引用移出,好让系统可以及时释放内存
sessionl.remove(se.getSession()); }
}----------------
jsp:<%
//把所有的session的id输出来
java.util.HashMap qq=SessionListener.sessionl;
if (qq.size()>0) {
java.util.Collection cc=qq.values();
Object aa[] =cc.toArray();
for (int i = 0; i < aa.length; i++) {
out.println( ((javax.servlet.http.HttpSession)aa[i]).getId()+"<br>");
}
}
%>让指定的session失效(传入参数为已知的sessionID,完全可以根据需要修改成用户名之类的参数)
invalid.jsp
------------------<%
//释放指定的sessionid的session信息
String sid=request.getParameter("sid");
if (sid!=null) {
java.util.HashMap qq=SessionListener.sessionl;
javax.servlet.http.HttpSession ss=(javax.servlet.http.HttpSession)qq.get(sid);
if (ss!=null) {
ss.invalidate();
}
}
%>如果要一个用户id只能一个用户在线,再加个全局的静态Map,用用户id作key,sessionId作value就可以了。
大概意思就是:用session和online同时确定一个人是不是登陆!