總述
前些天,無意之間想到這個問題,感覺挺實用,有必要整理一下。隨手寫了一個簡單的mode,感覺并不算難。思路理順其實挺簡單的。
為實現用戶不可同時登陸,只要想想現實中新浪,百度等,只要一處登陸就將另一處的給“擠”下去,就可以知道實現結果為何。然后再逆推之,即可形成較為清晰的思路。我們一起來探討一下。
首先,我們得明白用戶登錄使用什么登陸的,即用戶在線的原理。這只是將用戶的對象存放在了session中而已,然后再frame中進行調用,其他特定頁面也進行直接引用就行。那么實現“擠下來”的功能就是讓新生成的session有效,讓原來存放用戶的session失效就行。到此,大體思路已經有了。那怎么實現呢?
想要知道怎么實現,就必須要明白session存放用戶對象的過程了。在用戶登錄之后,我們可以得到用戶的對象user,而存放到session中需要執行session.setAttribute(key,value);
我們將用戶的userId或是其他的唯一標識存為key,將用戶對象存為值。這樣就能隨時隨地調用唯一用戶了。user存放的問題解決了,那相同 登錄 時session廢除的問題呢?
這個其實也不難,我們可以更具session的特性一樣,用map進行存貯,將用戶的標識存為key,而將其所對應的session存為value,那么當重復用戶登錄時,只需要取出對應的session,將其invalidate就行了。
至此,實現思路已經明了,聒噪了這么久,大家都急不可耐地想看代碼了吧?以下是代碼:
前置準備,jsp界面
界面很簡單,只是一個簡單的登錄界面
1
2
3
4
5
|
<form action = "<%=request.getContextPath()%>/UserWXPServlet" method = "post" > 用戶名š<input type = "text" name = "username" /><br/> 密碼š<input type = "text" name = "password" /><br/> <input type = "submit" value = "提交" /> </form> |
成功后跳轉頁面
歡迎:${sessionScope.user.username}登陸!<br/>
我這沒有寫失敗頁面,大家可以自己寫,失敗頁面也沒什么好說的了
entity和登錄的實現
user的javabean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
private String username; private String password; public User() { } public User(String user, String password) { super (); this .username = user; this .password = password; } public String getUsername() { return username; } public void setUsername(String username) { this .username = username; } public String getPassword() { return password; } public void setPassword(String password) { this .password = password; } |
登錄user的service實現方法,這里就不寫dao和接口了,一切以簡單為
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public boolean dologin(User user){ Properties pro = new Properties(); InputStream is = UserWXPServlet. class .getClassLoader().getResourceAsStream( "user_wxp.properties" ); String password = null ; System.out.println(is+ "--------->" +pro); if (user== null ){ return false ; } try { pro.load(is); password = pro.getProperty(user.getUsername()); if (user.getPassword()!= null &&user.getPassword().equals(password)){ System.out.println( "登陸成功" ); return true ; } } catch (IOException e) { e.printStackTrace(); } finally { if (is!= null ){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return false ; } |
登錄成功返回true,失敗則返回false。
Servlet和相應的邏輯工具類
接下來的代碼就到了真正操作用戶的代碼了
本人在這里定義了兩個類,一個工具類,一個核心servlet處理類
在工具類中加入了一些公共的元素,如以下代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/** * 每一個用戶存放一個session。便于各種操作!!! */ public static Map<String, HttpSession> mapSession = new HashMap<String,HttpSession>(); 用戶退出的代碼(必須飛廢除session或是remove相應的用戶對象): [java] view plain copy public static void userLogout(String username){ if (mapSession.get(username)!= null ){ //得到需要退出的用戶的session HttpSession session = mapSession.get(username); //在map<username,session>中移除該用戶,記住想要退出該用戶,必須將該session廢除或是remove掉user mapSession.remove(username); //得到session的所屬性合集 Enumeration e = session.getAttributeNames(); //刪除所有屬性 while (e.hasMoreElements()){ String sessionName = (String) e.nextElement(); session.removeAttribute(sessionName); } //廢除該session session.invalidate(); } } |
Servlet的代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter( "username" ); String password = request.getParameter( "password" ); User user = new User(username, password); UserService userService = new UserService(); HttpSession session = request.getSession(); if (userService.dologin(user)){ //登錄成功之后將用戶插入到session中 session.setAttribute( "user" , user); if (cheackSession(username)){ //如果該session在此之前已經存在,則將該用戶進行退出操作 DbUtil.userLogout(username); } //將新的session存放到map<username,session>中 DbUtil.mapSession.put(username, session); //操作成功,跳轉,此處最好為重定向,讓別人知道登錄成功了 request.getRequestDispatcher( "login" ).forward(request, response); return ; } //此處跳轉到失敗頁面,如果讀者有興趣,可以自行添加 } |
其中cheackSession(username) 的代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
/** * 檢查是否已經含有此session * @param username * @return true:已經存在,該刪! false:未存在 */ private boolean cheackSession(String username){ HttpSession session = DbUtil.mapSession.get(username); if (session!= null ){ return true ; } return false ; } |
最后附上Servlet的xml配置
1
2
3
4
5
6
7
8
9
10
11
12
|
<servlet> <description> 用于測試 ,用戶不可重復登錄 </description> <display-name>UserWXPServlet</display-name> <servlet-name>UserWXPServlet</servlet-name> <servlet- class >com.fingard.rabbit.wxp_test.Servlet.UserWXPServlet</servlet- class > </servlet> <servlet-mapping> <servlet-name>UserWXPServlet</servlet-name> <url-pattern>/UserWXPServlet</url-pattern> </servlet-mapping> |
以上所述是小編給大家介紹的Java實現用戶不可重復登錄功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!
原文鏈接:http://blog.csdn.net/qq_33347703/article/details/53905751