S2SH用户重复登录问题

  • 格式:doc
  • 大小:40.50 KB
  • 文档页数:5

写这个小功能花费了个人不少时间,终于搞定,就把功能的具体实现写下来已被不时之需。

同时,如果能帮到别人,那更是欣喜不已。

如果有写的不够好的地方,还希望大家能够指出。

部分代码摘自网上别的文章中,现已无法找到出处,还望见谅。

需求:用户不能重复登录,如果重复登录则后一用户将前面登录的用户踢出,并做出相应的提示;
开发框架:经典的s2sh
实现:采用session监听的方式实现
代码部分:
1、创建监听类
Java代码
1.package com.test.interceptor
2.
3.import javax.servlet.http.HttpSession;
4.import javax.servlet.http.HttpSessionAttributeListener;
5.import javax.servlet.http.HttpSessionBindingEvent;
6.import javax.servlet.http.HttpSessionEvent;
7.import javax.servlet.http.HttpSessionListener;
8.
9.import mon.constant.SysConstant;
10.import com.test.dto.SessionUser;
11.
12.public class SessionListener implements HttpSessionListener,Htt
pSessionAttributeListener {
13.
14. // 保存当前登录的所有用户
15. public static Map<HttpSession, SessionUser> loginUser = new
HashMap<HttpSession, SessionUser>();
16.
17. /**
18. * session创建时调用这个方法
19. */
20. @Override
21. public void sessionCreated(HttpSessionEvent se) {
22. }
23.
24. /**
25. * Session失效或者过期的时候调用的这个方法
26. */
27. @Override
28. public void sessionDestroyed(HttpSessionEvent se) {
29. // 如果session超时, 则从map中移除这个用户
30. loginUser.remove(se.getSession());
31. }
32.
33. /**
34. * 执行setAttribute的时候, 当这个属性本来不存在于Session
中时, 调用这个方法.
35. * @param se
36. */
37. @Override
38. public void attributeAdded(HttpSessionBindingEvent se) {
39. // 如果添加的属性是用户名, 则加入map中
40. if (se.getName().equals(SysConstant.SESSION_USER_ID)) {
41. SessionUser user = (SessionUser)se.getValue();
42. if(null != user){
43. destroyedOldSession(user.getUserId());
44. }
45. loginUser.put(se.getSession(),user);
46.
47. }
48.
49. }
50.
51. /**
52. * 当执行removeAttribute时调用的方法
53. * @param se
54. */
55. @Override
56. public void attributeRemoved(HttpSessionBindingEvent se) {
57. // 如果移除的属性是用户名, 则从map中移除
58. if (se.getName().equals(SysConstant.SESSION_USER_ID)) {
59. loginUser.remove(se.getSession());
60. }
61.
62. }
63.
64. /**
65. * 当执行setAttribute时 ,如果这个属性已经存在, 覆盖属性的
时候, 调用这个方法
66. * @param se
67. */
68. @Override
69. public void attributeReplaced(HttpSessionBindingEvent se) {
70. // 如果改变的属性是用户名, 则跟着改变map
71. if (se.getName().equals(SysConstant.SESSION_USER_ID)) {
72. loginUser.put(se.getSession(),(SessionUser)se.getVa
lue());
73. }
74. }
75.
76. /**
77. * 如果当前用户已经登录,则将其session销毁
78. * @param userId
79. */
80. private void destroyedOldSession(Long userId){
81. for(Entry<HttpSession,SessionUser> entry : loginUser.en
trySet()){
82. SessionUser user = entry.getValue();
83. Long tempUserId = user.getUserId();
84. if(null != user && userId.equals(tempUserId)){
85. HttpSession session = entry.getKey();
86. session.removeAttribute(SysConstant.SESSION_USE
R_ID);
87. session.setAttribute(SysConstant.SESSION_UDER_R
E_LOGIN, SysConstant.SESSION_UDER_RE_LOGIN);
88. loginUser.remove(session);
89. }
90. }
91. }
92.
93.}
其中SessionUser为用户登录时存放在session中的用户的pojo 对象,此处就不再贴出此实体类的代码;
2、web.xml中添加配置
Xml代码
1.<!-- 用户重复登录监听 -->
2. <listener>
3. <listener-class>com.test.interceptor.SessionListener</l
istener-class>
4. </listener>
3、在判断用户会话是否过期,是否拥有权限的代码中添加如下代码(此代码需放在会话过期判断和权限判断前面,不然会导致提示会话过期,而不是提示已经被踢)
Java代码
1.String reLoginStr = (String) request.getSession().getAttribute(
SysConstant.SESSION_UDER_RE_LOGIN);
2. if(SysConstant.SESSION_UDER_RE_LOGIN.equals(reLoginStr)
){
3. // 做出判断后,即将判断的标志消除,防止影响后续操作
4. request.getSession().removeAttribute(SysConstant.SE
SSION_UDER_RE_LOGIN);
5. // 已在别的地方登录;
6. return SysConstant.SESSION_UDER_RE_LOGIN;
7. }
4、struts.xml中配置中添加用户被踢后跳转的页面的<result>
Java代码
1.<global-results>
2. <result name="reLogin" type="redirect">/?error=reLogin</
result>
3.</global-results>
5、jsp页面中显示提示代码
Html代码
1.<div>
2. <span>
3. <s:if test="#request.error=='reLogin'">您的帐号已在
别的地方登录,您已被迫退出。

若有疑问请联系管理员,谢谢!</s:if>
4. </span>
5.</div>。