http://xiaozhuo.javaeye.com/blog/445461
解决两个问题:
1. 实现在线用户列表
2. 当用户在异地登录后,使前一次登录自动退出
实现方法:
用户登录时,会创建一个session,用于保存用户信息。将所有用户登录时的session值与ID存入ServletContext中,显示在线列表的时候,就从ServletContext中取得用户登录的session值,从中取得用户信息。
1. 登录:
先从ServletContext中取出存放用户登录的session 相关信息,检查这个列表,如果已经存在相同的登录信息,则说明用户之前已经登录过,移除前面一条记录。
再把此次登录的信息加入到ServletContext中。
2.监听:
实现SessionListener类,当session失效的时候,从ServletContext中移除相应记录。
3.过滤:
过滤所有页面,sesison失效后转向登录页面。但是要实现用户二次登录后强制先前的登录失效,需要在这里控制。
登录时存入的是session值和session ID,用户二次登录时移除了前线记录,存入的session值是相同的,但是ID却不同。
当第一次登录的页面请求的时候,在这里检查ServletContext中是否存在当前的session值与ID记录。如果没有就销毁这个session。
参考代码:
存放的时候有很多中方法,我选择的是将session值与ID先存入一个List,在将这个List存入另一个List,再存到ServletContext中。
代码仅供参考,有不合理的地方,希望大家给出意见。
============================1. 登录部分============================
- //先从ServletContext中获得存放sessioninfo的List
- List userlist = (List) this .servlet.getServletContext()
- .getAttribute("userlist" );
- //如果是首个用户登录,sessionlist为空,new一个
- if (userlist == null ) {
- userlist = new ArrayList();
- }
- //遍历List
- for ( int i = 0 ; i < userlist.size(); i++) {
- List sessionInfoTemp = (List) userlist.get(i);
- //检查是否存在一个与当前session值相同,但是ID不同的记录
- if (sessionInfoTemp.get( 0 ).toString().equals(session.getAttribute( "emp" ).toString())&& !(sessionInfoTemp.get( 1 ).equals(session.getId()))) {
- //如果存在,remove这一记录
- userlist.remove(sessionInfoTemp);
- }
- }
- // 把session值、ID 存入 sessioninfo
- List sessioninfo = new ArrayList();
- sessioninfo.add(session.getAttribute("emp" ));
- sessioninfo.add(session.getId());
- //sessioninfo 存入 List
- userlist.add(sessioninfo);
- //List存入ServletContext
- this .servlet.getServletContext().setAttribute( "userlist" , userlist);
//先从ServletContext中获得存放sessioninfo的List
List userlist = (List) this.servlet.getServletContext()
.getAttribute("userlist");
//如果是首个用户登录,sessionlist为空,new一个
if (userlist == null) {
userlist = new ArrayList();
}
//遍历List
for (int i = 0; i < userlist.size(); i++) {
List sessionInfoTemp = (List) userlist.get(i);
//检查是否存在一个与当前session值相同,但是ID不同的记录
if(sessionInfoTemp.get(0).toString().equals(session.getAttribute("emp").toString())&& !(sessionInfoTemp.get(1).equals(session.getId()))) {
//如果存在,remove这一记录
userlist.remove(sessionInfoTemp);
}
}
// 把session值、ID 存入 sessioninfo
List sessioninfo = new ArrayList();
sessioninfo.add(session.getAttribute("emp"));
sessioninfo.add(session.getId());
//sessioninfo 存入 List
userlist.add(sessioninfo);
//List存入ServletContext
this.servlet.getServletContext().setAttribute("userlist", userlist);
============================2. 监听部分============================
- public void sessionDestroyed(HttpSessionEvent arg0) {
- // TODO Auto-generated method stub
- HttpSession session = arg0.getSession();
- if (session.getAttribute( "emp" )!= null ){
- List list = (List)session.getServletContext().getAttribute("userlist" );
- List userTemp = new ArrayList();
- userTemp.add(session.getAttribute("emp" ));
- userTemp.add(session.getId());
- list.remove(userTemp);
- session.getServletContext().setAttribute("userlist" , list);
- }
- }
public void sessionDestroyed(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
HttpSession session = arg0.getSession();
if(session.getAttribute("emp")!=null){
List list = (List)session.getServletContext().getAttribute("userlist");
List userTemp = new ArrayList();
userTemp.add(session.getAttribute("emp"));
userTemp.add(session.getId());
list.remove(userTemp);
session.getServletContext().setAttribute("userlist", list);
}
}
============================3. 过滤部分============================
- public void doFilter(ServletRequest req, ServletResponse res,
- FilterChain chain) throws IOException, ServletException {
- HttpServletRequest request = (HttpServletRequest) req;
- HttpServletResponse response = (HttpServletResponse) res;
- HttpSession session = request.getSession();
- /**
- * 同一用户二次登陆问题 用户请求的提交到这里,通过检查List总的记录销毁session
- */
- // 从ServletContext中取出List
- List sessionlist = (List) session.getServletContext().getAttribute(
- "userlist" );
- if (sessionlist == null ) {
- sessionlist = new ArrayList();
- }
- // 用于记录状态
- boolean temp = false ;
- Iterator it = sessionlist.iterator();
- while (it.hasNext()) {
- List sessioninfo = (List) it.next();
- /**
- * 判断: 如果sessioninfo中没有当前session的值与ID信息,则表明该用户已经第二次登陆了
- * 登陆的时候第一次登陆时候的信息被从List中移除了。
- */
- if (sessioninfo.get( 0 ).toString().equals(
- session.getAttribute("emp" ).toString())
- && sessioninfo.get(1 ).equals(session.getId())) {
- // session值与当前ID匹配
- temp = true ;
- }
- }
- // 存在了第二次登陆,销毁session
- if (!temp) {
- session.invalidate();
- }
- String strSession = null ;
- try {
- strSession = session.getAttribute("emp" ).toString();
- } catch (Exception e) {
- }
- /**
- * 如果session为空,返回登陆页面
- */
- if (strSession == null ) {
- response.setCharacterEncoding("gb2312" );
- response
- .getOutputStream() .print("<script>window.top.location.href='/index.jsp';alert('超时或账号在其它地方登录,请重新登录!');</script>" );
- } else {
- chain.doFilter(req, res);
- }
- }