引用:

知道了session混乱产生的原因之后,也就知道了问题的根源。同时也引出了很多的问题:

1、如何记录住在线人员(这里只有帐号的系统用户,不包括访客);

2、如何限制同一个帐号在同一时间段内只能够登陆一次系统?

3、如何限制不同的用户在同一台机器上登陆系统?

4、管理员如何踢人?

我们首先来分析上面的问题:

首先在服务器端当用户通过身份验证成功登陆系统之后,我们将此用户的信息记录住(OnLineUserManager.java),包括帐号、登陆日期、机器的IP地址、session的IDsession对象。(记住session的ID极其重要,因为服务器识别session是根据id,只要id相同,服务器就认为是同一个用户);

(上面解决了问题1)

这样当用户登陆系统的时候我们首先根据帐号判断用户是否登陆了,如果已经登陆,提示用户;(这样就解决了问题2)

如果未登陆,判断用户的session的id是否已经在用户的信息OnLineUserManager里面了,如果是提示用户

关闭当前窗口,重新点击IE打开一个新的浏览器窗口。(这样session就不会混乱了)。

如果要限制不同的用户在同一台机器上登陆系统?这个就要根据IP地址来判断了。如果OnLineUserManager中

有通过这个机器登陆系统的用户,那么就提示用户同一台机器只能够一个帐号登陆;

注意:如果用户使用了代理服务器,那么此方法失效。这个方法适用于管理规范的用户,客户在局域网内使用,每个客户有固定的ip。)

问题4如何踢人?你想想OnLineUserManager中记录了用户session对象,只要根据用户的帐号找到对应的

session对象,然后session.invalidate();这样就可以彻底的将捣乱的人提出系统了。

 

===============需要注意的是OnLineUserManager必须是线程安全的=我的实现如下==============



1. package com.work.qxgl.login;  
2.   
3.   
4.   
5. import java.util.Vector;  
6.   
7.   
8.   
9. import org.apache.commons.logging.Log;  
10.   
11. import org.apache.commons.logging.LogFactory;  
12.   
13.   
14.   
15. import com.work.util.DateUtil;  
16.   
17.   
18.   
19. /**
20. 
21.  * 统计在线用户数。前提是登录的时候限制一个用户只能够在系统中登录一次。 有了这个功能,管理员就可以管理在线用户,如果谁不服从管理,就可以从系统中踢出去。
22. 
23.  * TODO 将jsp放到WEB-INF后面,然后所有的URL必须通过struts的action调用。 使用拦截器Interceptor来实现权限的控制!
24. 
25.  * 或者通过web中的Filter来实现权限控制! 实现权限管理系统日志的记录!
26. 
27.  * 
28. 
29.  * @author wangmingjie
30. 
31.  * 
32. 
33.  */  
34.   
35. public class OnLineUserManager {  
36.   
37. private static Log log = LogFactory.getLog(OnLineUserManager.class);  
38.   
39. private Vector<OnLineUser> users = null;  
40.   
41.   
42.   
43.   
44.   
45. private OnLineUserManager() {  
46.   
47. new Vector<OnLineUser>();//在构造函数中初始化  
48.   
49.     }  
50.   
51.       
52.   
53. static class SingletonHolder {  
54.   
55. static OnLineUserManager instance = new OnLineUserManager();  
56.   
57.     }  
58.   
59.   
60.   
61. /**
62. 
63.      * 单例模式。这样简单而且能够保证线程安全。
64. 
65.      * 
66. 
67.      * @return
68. 
69.      */  
70.   
71. public static OnLineUserManager getInstance() {  
72.   
73. return SingletonHolder.instance;  
74.   
75.     }  
76.   
77.   
78.   
79. /**
80. 
81.      * 获取到登录用户的数量。
82. 
83.      * 
84. 
85.      * @return
86. 
87.      */  
88.   
89. public synchronized int getCount() {  
90.   
91.         users.trimToSize();  
92.   
93. return users.capacity();  
94.   
95.     }  
96.   
97.   
98.   
99. /**
100. 
101.      * 通过用户帐号判断该用户是否存在! 必须保证是线程安全的。
102. 
103.      * 
104. 
105.      * @param userAccount
106. 
107.      * @return
108. 
109.      */  
110.   
111. public synchronized boolean existUser(String userAccount) {  
112.   
113.         users.trimToSize();  
114.   
115. boolean existUser = false;  
116.   
117. for (int i = 0; i < users.capacity(); i++) {  
118.   
119. if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {  
120.   
121. true;  
122.   
123. break;  
124.   
125.             }  
126.   
127.         }  
128.   
129. return existUser;  
130.   
131.     }  
132.   
133.       
134.   
135. /**
136. 
137.      * @param sessionid
138. 
139.      * @return
140. 
141.      */  
142.   
143. public synchronized boolean existSession(String sessionid) {  
144.   
145.         users.trimToSize();  
146.   
147. boolean existUser = false;  
148.   
149. for (int i = 0; i < users.capacity(); i++) {  
150.   
151. if (sessionid.equals(((OnLineUser) users.get(i)).getSessionId())) {  
152.   
153. true;  
154.   
155. break;  
156.   
157.             }  
158.   
159.         }  
160.   
161. return existUser;  
162.   
163.     }  
164.   
165.       
166.   
167.   
168.   
169. /**
170. 
171.      * 删除用户
172. 
173.      * 
174. 
175.      * @param userAccount
176. 
177.      * @return
178. 
179.      */  
180.   
181. public synchronized boolean deleteUser(String userAccount) {  
182.   
183.         users.trimToSize();  
184.   
185. if (existUser(userAccount)) {  
186.   
187. int currUserIndex = -1;  
188.   
189. for (int i = 0; i < users.capacity(); i++) {  
190.   
191. if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {  
192.   
193.                     currUserIndex = i;  
194.   
195. break;  
196.   
197.                 }  
198.   
199.             }  
200.   
201. if (currUserIndex != -1) {  
202.   
203.                 users.remove(currUserIndex);  
204.   
205.                 users.trimToSize();  
206.   
207. "用户" + userAccount + "退出系统"  
208.   
209.                         + DateUtil.getCurrentDateTime());  
210.   
211. "在线用户数为:" + getCount());  
212.   
213. return true;  
214.   
215.             }  
216.   
217.         }  
218.   
219. return false;  
220.   
221.     }  
222.   
223.       
224.   
225. /**
226. 
227.      * 根据用户帐号,获取在线用户信息
228. 
229.      * @param userAccount
230. 
231.      * @return
232. 
233.      */  
234.   
235. public synchronized OnLineUser getUser(String userAccount) {  
236.   
237.         users.trimToSize();  
238.   
239. if (existUser(userAccount)) {  
240.   
241. int currUserIndex = -1;  
242.   
243. for (int i = 0; i < users.capacity(); i++) {  
244.   
245. if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {  
246.   
247.                     currUserIndex = i;  
248.   
249. break;  
250.   
251.                 }  
252.   
253.             }  
254.   
255. if (currUserIndex != -1) {  
256.   
257. return  users.get(currUserIndex);  
258.   
259.             }  
260.   
261.         }  
262.   
263. return null;  
264.   
265.     }  
266.   
267.   
268.   
269. /**
270. 
271.      * 获取到在线用户的信息。
272. 
273.      * 
274. 
275.      * @return
276. 
277.      */  
278.   
279. public synchronized Vector<OnLineUser> getOnLineUser() {  
280.   
281. return users;  
282.   
283.     }  
284.   
285.   
286.   
287. public synchronized void addUser(OnLineUser onLineUser) {  
288.   
289.         users.trimToSize();  
290.   
291. if (!existUser(onLineUser.getUserAccount())) {  
292.   
293.             users.add(onLineUser);  
294.   
295. "/t登录到系统/t" + DateUtil.getCurrentDateTime());  
296.   
297. // 通过request才能够获取到用户的ip等信息  
298.   
299. else {  
300.   
301. "已经存在");  
302.   
303.         }  
304.   
305. "在线用户数为:" + getCount());  
306.   
307.     }  
308.   
309.   
310.   
311. }


 

 

 ==================OnLineUser.java============================



1. package com.work.qxgl.login;  
2.   
3.   
4.   
5. import java.io.Serializable;  
6.   
7.   
8.   
9. import javax.servlet.http.HttpSession;  
10.   
11.   
12.   
13. /**
14. 
15.  * @author wangmingjie
16. 
17.  * @date 2008-6-30下午04:56:37
18. 
19.  */  
20.   
21. public class OnLineUser implements Serializable {  
22.   
23.   
24.   
25. /**
26. 
27.      * 
28. 
29.      */  
30.   
31. private static final long serialVersionUID = 5461473880667036331L;  
32.   
33.       
34.   
35. private String userId; //用户id  
36.   
37. private String userAccount; //用户帐号  
38.   
39. private String userName; //用户名称   
40.   
41.       
42.   
43. private String loginTime; //登陆时间戳  
44.   
45.       
46.   
47. private String sessionId; //session的ID  
48.   
49. private String userIp ;//ip地址  
50.   
51.       
52.   
53. private HttpSession session; //记住session对象,测试能否用来将人员踢出系统  
54.   
55.       
56.   
57.   
58.   
59. public String getUserId() {  
60.   
61. return userId;  
62.   
63.     }  
64.   
65.   
66.   
67. public void setUserId(String userId) {  
68.   
69. this.userId = userId;  
70.   
71.     }  
72.   
73.   
74.   
75. public String getUserAccount() {  
76.   
77. return userAccount;  
78.   
79.     }  
80.   
81.   
82.   
83. public void setUserAccount(String userAccount) {  
84.   
85. this.userAccount = userAccount;  
86.   
87.     }  
88.   
89.   
90.   
91. public String getUserName() {  
92.   
93. return userName;  
94.   
95.     }  
96.   
97.   
98.   
99. public void setUserName(String userName) {  
100.   
101. this.userName = userName;  
102.   
103.     }  
104.   
105.   
106.   
107. public String getSessionId() {  
108.   
109. return sessionId;  
110.   
111.     }  
112.   
113.   
114.   
115. public void setSessionId(String sessionId) {  
116.   
117. this.sessionId = sessionId;  
118.   
119.     }  
120.   
121.   
122.   
123. public String getUserIp() {  
124.   
125. return userIp;  
126.   
127.     }  
128.   
129.   
130.   
131. public void setUserIp(String userIp) {  
132.   
133. this.userIp = userIp;  
134.   
135.     }  
136.   
137.   
138.   
139. public HttpSession getSession() {  
140.   
141. return session;  
142.   
143.     }  
144.   
145.   
146.   
147. public void setSession(HttpSession session) {  
148.   
149. this.session = session;  
150.   
151.     }  
152.   
153.   
154.   
155. public String getLoginTime() {  
156.   
157. return loginTime;  
158.   
159.     }  
160.   
161.   
162.   
163. public void setLoginTime(String loginTime) {  
164.   
165. this.loginTime = loginTime;  
166.   
167.     }  
168.   
169. public String toString(){  
170.   
171. return  "OnLineUser{userId="+userId+",userAccount="+userAccount  
172.   
173. ",userName"+userName+",loginTime="+loginTime+",userIp="+userIp+",sessionId="+sessionId+"}";  
174.   
175.     }  
176.   
177.       
178.   
179. //===============下面的数据只有在系统登陆日期中记录==================================  
180.   
181. //  private String logoutTime;//退出时间戳;  
182.   
183. //  private String logoutType;//退出方式 “session超时退出”;“1主动退出”  
184.   
185. //  private String lastAccessedTime;// 最后访问时间  
186.   
187.   
188.   
189. }