用戶不可重複登錄 java實現

總述

前些天,無意之間想到這個問題,感覺挺實用,有必要整理一下。隨手寫了一個簡單的mode,感覺並不算難。思路理順其實挺簡單的。
爲實現用戶不可同時登陸,只要想想現實中新浪,百度等,只要一處登陸就將另一處的給“擠”下去,就可以知道實現結果爲何。然後再逆推之,即可形成較爲清晰的思路。我們一起來探討一下。
首先,我們得明白用戶登錄使用什麼登陸的,即用戶在線的原理。這只是將用戶的對象存放在了session中而已,然後再frame中進行調用,其他特定頁面也進行直接引用就行。那麼實現“擠下來”的功能就是讓新生成的session有效,讓原來存放用戶的session失效就行。到此,大體思路已經有了。那怎麼實現呢?
想要知道怎麼實現,就必須要明白session存放用戶對象的過程了。在用戶登錄之後,我們可以得到用戶的對象user,而存放到session中需要執行session.setAttribute(key,value); 我們將用戶的userId或是其他的唯一標識存爲key,將用戶對象存爲值。這樣就能隨時隨地調用唯一用戶了。user存放的問題解決了,那相同 登錄 時session廢除的問題呢?
這個其實也不難,我們可以更具session的特性一樣,用map進行存貯,將用戶的標識存爲key,而將其所對應的session存爲value,那麼當重複用戶登錄時,只需要取出對應的session,將其invalidate就行了。
至此,實現思路已經明瞭,聒噪了這麼久,大家都急不可耐地想看代碼了吧?以下是代碼:

前置準備,jsp界面

界面很簡單,只是一個簡單的登錄界面
<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
	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和接口了,一切以簡單爲

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處理類
在工具類中加入了一些公共的元素,如以下代碼:

/**
	 * 每一個用戶存放一個session。便於各種操作!!!
	 */
	public static Map<String, HttpSession> mapSession = new HashMap<String,HttpSession>();

用戶退出的代碼(必須飛廢除session或是remove相應的用戶對象):

	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的代碼如下:
	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) 的代碼如下:
	/**
	 * 檢查是否已經含有此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配置
	<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>

以上就是所有實現的代碼,大家如果有什麼建議,還望能夠一起探討。有什麼問題,本人會盡快進行解答的大笑







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章