站内搜索: 请输入搜索关键词

当前页面: 开发资料首页JSP 专题[求助] jsp如何判断该用户已经在另外一台机器上登陆。

[求助] jsp如何判断该用户已经在另外一台机器上登陆。

摘要: [求助] jsp如何判断该用户已经在另外一台机器上登陆。


有位前辈告诉我:新建一表记录所有已登陆用户的ID,设置判断在线时间,超过该时间限制和用户退出,就删除表中用户的ID,保证此表中所有用户为在线。
对每一个登陆用户,登陆时判断ID是否在上面所说的ID表中,若存在,表示已登陆,给出已登陆信息,反之则让之正常登陆

但是有一点不太明白,就是设置判断在线时间,哪位前辈知道,拜托了。

另外,是不是应该在登陆的时候把用户名和密码放在session中,然后在后台的每个操作前都判断一下对应session中的用户名和密码是否在该表中存在,如果存在则可以进行操作,如不存在,则提醒登陆,是这样吗


帮顶


谢谢 ,呵呵


可以在用户表中加上一个字段 来标志用户当前是否在线 如果用户登陆 设置为1 如果离线设置为0 别的机器登陆时候去查看一下数据库当前为几


这个有没有答案哦

可以在用户表中加上一个字段 来标志用户当前是否在线 如果用户登陆 设置为1 如果离线设置为0 别的机器登陆时候去查看一下数据库当前为几
实际项目中行不通的


为什么行不通呢 我没有实际做过


为什么行不通啊,前辈

那究竟哪一种做法好呢,就是一般项目中大家都用的那种方法。


SessionListener


楼上的前辈,能不能说的具体点啊,在下新手,请前辈不吝赐教


另外,是不是应该在登陆的时候把用户名和密码放在session中,然后在后台的每个操作前都判断一下对应session中的用户名和密码是否在该表中存在,如果存在则可以进行操作,如不存在,则提醒登陆,是这样吗

=================================================================================

这个应该是application干的事,不是session,session是对应某个用户的会话


哦,这样,那前辈能不能具体说一下该怎么做呢,我都迷茫了,不知道怎么下手。


可以在用户表中加上一个字段 来标志用户当前是否在线 如果用户登陆 设置为1 如果离线设置为0 别的机器登陆时候去查看一下数据库当前为几


这个是行不通的!
按你说的超过该时间限制就删除,我想你要是用户的话,动不动就重复登陆一次你绝对不爽!

但是不删除!假如那个用户没有正常退出那你怎么消除数据表里面的已经登陆?所以这个问题我也想知道该怎么解决!


session不好吧,用户多了太耗资源。
我觉得就是建一个新表,将已经登录的用户写入库中,还有他的登录时间,然后判断时间就可以了。
判断时间可以用下面的语句:
select * from a where time<'02:00:00'


判断时间能不能说的具体点啊。就是说还是要设置登陆时间,一旦超过了时间限制就把新表中的该记录删除吗。


可以在用户表中加上一个字段 来标志用户当前是否在线 OK


但是有前辈说这种办法在实际项目中行不通,各有各的说法,到底哪种做法才是最合理的呢。


建一个类:
package test;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MySL implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent hse) {
hse.getSession().getServletContext().setAttribute((String)hse.getSession().getAttribute("username"),"dreamover");
}

public void sessionDestroyed(HttpSessionEvent hse) {
hse.getSession().getServletContext().removeAttribute((String)hse.getSession().getAttribute("username"));
}
}
web.xml中web-app中加入

test.MySL


jsp页面中用
if(session.getServletContext().getAttribute((String)session.getAttribute("username"))!=null){
out.println(session.getAttribute("username")+"is login");
}
大致是这样,中间有的地方可能有问题,再查一下相关资料吧


这个是存在application里的,登录用户多的话,可以效率有问题,也可以把用户名存在数据库里,改一下相应的部分就可以了


用B/S结构实现这样的东西很难的,登陆的时候可以做到,但是用户下线了。如果通过SESSION来判断的话必须等到会话超时。中间这段时间用户就不能用。如果确实需要的话估计得看法插件什么的。或者集成到应用程序中。


HttpSessionListener我还是第一次接触,想想不会的还真多,很想尝试一下,我从网上找到了一段代码就是计算现在在线的用户列表的,代码如下,因为有不懂的地方还望前辈指教:
package SessionCounter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import com.oztime.right.UserObject;

public class SessionCounter implements HttpSessionListener {

private static int activeSessions = 0;
private static Vector v= new Vector();
public void sessionCreated(HttpSessionEvent se) {
}


public static void createsession(HttpSessionEvent se ) {
UserObject user1 =(UserObject)se.getSession().getAttribute("UserObject");
if(v.contains(user1)==false){
v.add(user1);
activeSessions++;
System.out.println("===================用户名称=================="+user1.getName());
System.out.println("===================用户数量=================="+activeSessions);
}

}

public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
UserObject user2=(UserObject)se.getSession().getAttribute("UserObject");
if(v.contains(user2)==true){
v.remove(user2);
activeSessions--;
System.out.println("===================removed=================="+user2.getName());
}

}
public static void Destroysession(UserObject user) {
//System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
//UserObject user3=(UserObject)se.getSession().getAttribute("UserObject");
System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"+user.getName());
if(v.contains(user)==true){
v.removeElement(user);
activeSessions--;
System.out.println("====================================="+user.getName()+"---退出登录!!!");
}

}



public static int getActiveSessions() {
return activeSessions;

}

public static Vector getVector() {
return v;
}
}

在用户登陆后调用的


SessionCounter.createsession(new HttpSessionEvent(session));

SessionCounter.Destroysession(user); //注user 为用户实体

我要请教的是:1。当用户登陆时在登陆的action里调用
SessionCounter.createsession(new HttpSessionEvent(session)); 这个方法,是不是就把这时登陆的用户的信息存到了session监听器里了。
2,当用户退出登陆时调用SessionCounter.Destroysession(user); 这个方法, 是不是就把这条用户信息从监听器里删除了。
3,当要判断该用户是否已登陆,对于这个类应该如何来判断呢?这是我最不懂的地方
4,public void sessionDestroyed(HttpSessionEvent se)这个方法是在什么时候调用。
5,当用户非法退出时这个用户的信息是不是就不存在于监听器中了。也不存在判断在线时间的问题了吧。
6,session监听器能够监听到所有登陆的用户,就是说是不是得通过遍历它的vector来判断某个时刻登陆的用户是否已登陆,也就是说达到了判断同一时刻某个用户是否在另一台机器上登陆的作用。那如果要在后台的每个操作前都判断一下在同一台机器上刚刚登陆的用户是否还有线,这个应该怎么做啊。




最简单的就是在application里面判断


建议直接用现成的直接支持单点登陆的软件,比如CAS等


to hellen_cap()

你写的这个根本就是在乱弹琴,有概念上的错误,建议你先找资料仔细了解一下session是个什么概念,干什么用的,怎么用,是个什么东东。


是啊,我现在也有点乱了,那我先上网查查看吧。有问题的话还请前辈继续关注我的贴子,谢谢。


找不到了,越看越乱,session就是针对每个用户的购物车,我就知道这个了,但是session监听器既然能实现在线人数的统计,那它也能监听到所有在线的用户吧。那用户登陆的时候是不是应该从监听器里查找是否有同一个用户已经在线。然后在后台的每个操作前难道只用判断一下session.getServletContext().getAttribute((String)session.getAttribute("username"))!=null 就行了?

不知道了,前辈就直接了当的告诉我吧

另外如果用application又应该怎么做呢,我是刚刚工作,经验不足,身在落后的地方,连个会java的人都没有。


SESSION事件不可靠


up


我做了一套.不过比较麻烦.
首先你得实现attributeAdded, attributeReplaced, sessionDestroyed这几个方法,
用3个静态的ArrayList接session对象; 用其中2个ArrayList按一定顺序记录session的ID和对应的用户ID,另一个做为记录删除状态session的ID.
做一个头页,里面要一直session.setAttribute(),随便在里面建个session,只要触发attributeReplaced就行了,你的每个页面都要被include到此头页去,这样少写很多重复代码.
在每次用户登陆的时候去判断有没有此用户的ID,如果有,就应该提示他重新登陆,也就是说只要他能强制登陆成功,那么就应该把这个存用户ID的ArrayList对应放session的ID位置的的值取出来,放到要删除的ArrayList里,然后在attributeReplaced的时候判断一下删除的ArrayList中有无此session的ID.如果有那么就把他的session清除,然后清掉删除的ArrayList中对应的值.
超时用户的清楚,直接在sessionDestroyed判断.


如果要使用数据库,那么就用三字段表示,第一个是session的ID,第二个是用户的ID,第三个是标志状态.要是这样.你要时时刻刻的连接数据库.会造成服务器忙和连接不上数据库的情况.


还要考虑用户关闭浏览器退出的情况,但据我所知,目前尚无很好的解决办法。
在ASP里只能用Session_OnEnd勉强将就!!!


不用啊,前一用户关闭浏览器后,虽然此帐号处于使用状态,但是你可以使用强制登陆的方法进入,这样就会去触发把前一用户的Session ID 放到删除的ArrayList中去.到超时的时候就会直接把这个没用的Session ID 删除掉.


to hellen_cap()

在jsp中许多概念确实比较乱,没有基础看的话确实容易混,给你个建议吧,你可以找本asp方面的书,看看asp中session的概念及用法,在asp中application、session、request、response等内置对象设计得非常清晰合理,jsp设计时也是借鉴了asp中的许多概念,asp看差不多后再转回来看看jsp,有些概念可能就会容易理解得多


给你个思路:
如果是做成 BS,CS 都是单点登录的, 可以写个 SOCKET 类, 这个类只 接收用户的连接请求。
判断一个USERID是否在 一个HASHSET 中, 如果存在,则表示已经登录。
当然,这样的话,如果是通过WEB 方式登录,则还要处理, SESSION 的几个侦听接口,
发送相应的请求到SOCKET ,例如用户的退出行为,则需要从 HASHSET 中删除USERID。

如果只作 纯BS 的单点登录,你尽管把登录成功的用户的USERID 放进 APPLICATION 返回内。
然后进行判断。




to AreamArgentateOfWing(梦幻银翼)

你的做法,可能老一点版本jsp中没有sesionlistener标准的时候需要这么做,现在根本没必要,现在如果放着sessionlistener不用,用这种使用麻烦,且不可靠的做法就是给自己找麻烦


用户离线的判断是最大的难点!


to dreamover(梦醒了)

你说我没用上??我只是告诉他在那些方法中加入要写的内容.


session监听不行么?


谢谢各位前辈厚爱,看来这个问题也存在争议啊

不过总结下来好像还是用sessionlistener更好点。不过有一点不懂的还是用户登陆的时候是不是应该从监听器里查找是否有同一个用户已经在线。这个具体怎么实现啊   然后在后台的每个操作前只用判断一下session.getServletContext().getAttribute((String)session.getAttribute("username"))!=null 就行了吗?


to dreamover(梦醒了)前辈

前辈看起来好像一直在用这个呢,就告诉我吧。我想还是具体看到了代码,才能理解的透彻点,前辈 可以贴代码吗?



session.getServletContext()作用相当于application,你实际上还是有些概念不清楚,代码前面已经写过了

建一个类MySessionListener:
package test;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/*
这个类不用在代码中显式调用(没有MySessionListener msl=new MySessionListener()这种代码),这个是容器自动跟踪控制的
*/
public class MySessionListener implements HttpSessionListener {

/*
用户连接上本网站的时候,容器会自动调用此方法为每个用户创建一个session,session.getAttribute("someword")只是针对每个用户可见的,session.getServletContext().getAttribute("someword")才是针对整个网站可见的,所以把每个用户登录后的id要存在session.getServletContext()里。
*/
public void sessionCreated(HttpSessionEvent hse) {

hse.getSession().getServletContext().setAttribute((String)hse.getSession().getAttribute("username"),"dreamover");
}

/*
这个是每个用户断开会话时调用的方法,那这个用户从session.getServletContext()中移除,这个方法,因为http是无状态协议,所以只能是容器判断某个时间段内用户都没有再连接网站,来判断这个用户可能关掉浏览器走开了,调用此方法销毁这个用户的session
*/
public void sessionDestroyed(HttpSessionEvent hse) {
hse.getSession().getServletContext().removeAttribute((String)hse.getSession().getAttribute("username"));
}
}
web.xml中web-app中加入


↑返回目录
前一篇: 招 Java程序员,要求有WAP开发经验.
后一篇: 在写jsp的时候有没有工具让关键字可以变色呢