基於SSH的單用戶單賬戶登錄全過程。

 

[Author:Topcss - Time:09.7.13]

上次貼僞代碼時,有不少人說想要源碼,今天抽時間寫了一個。

概念:

所謂“單用戶單賬戶登錄”是指:在同一系統中,一個用戶名不能在兩個地方同時登錄。

我們參照 QQ 實現效果:

當某賬號在 A 處登錄後,在未退出的情況下,如果再到 B 處登錄,那麼,系統會擠下 A 處登錄的賬號。

先看看僞代碼: http://www.iteye.com/post/1049924 ,因爲我會按照這個流程來實現。

環境:

Tomcat 6 jdk6 MyEclipse7

Struts1.2+Hibernate+Spring

好,開工:

第一步:搭架子,把 SSH 整合起來。參照:

http://sites.google.com/site/topcss/struts-spring-hibernate-de-ji-cheng

第二步:編寫代碼

1 、編寫在線用戶類:

package net.jiakuan.books.common;

import java.util.HashMap ;

import java.util.Map ;

public class OnlineUserMap

{

public static Map<String , String > onlineuser = new HashMap<String , String >();

/**

* 得到在線用戶

* @return

*/

public static Map<String , String > getOnlineuser()

{

return onlineuser;

}

/**

* 添加在線用戶

* @param sessionId

* @param userName

* @return

*/

public void addOnlineUser(String userId, String sessionId)

{

onlineuser.put(userId, sessionId);

}

/**

* 得到sessionId

* @param userName

* @return

*/

public String getSessionId(String userName)

{

return onlineuser.get(userName);

}

/**

* 判斷用戶是否登錄

* @param name

* @return

*/

public boolean isLogin(String userName)

{

return onlineuser.containsKey(userName);

}

/**

* 移除用戶

* @param userName

*/

public void removeUser(String userName)

{

onlineuser.remove(userName);

}

}

2 、系統參數類

package net.jiakuan.books.common;

public class SystemParameter

{

public static final String SESSION_USER_NAME = "loginUser" ; // SESSION 中的鍵名

}

3 Session 監聽器

package net.jiakuan.books.webs.listener;

import javax.servlet.http.HttpSessionAttributeListener;

import javax.servlet.http.HttpSessionBindingEvent;

import net.jiakuan.books.common.OnlineUserMap;

import net.jiakuan.books.common.SystemParameter;

public class UserLoginListener implements HttpSessionAttributeListener

{

public void attributeAdded(HttpSessionBindingEvent evt)

{

String username = evt.getName();

String sessionId = evt.getSession().getId();

if (username == SystemParameter.SESSION_USER_NAME)

{

new OnlineUserMap().addOnlineUser(username, sessionId);

}

}

public void attributeRemoved(HttpSessionBindingEvent evt)

{

String username = evt.getName();

String sessionId = evt.getSession().getId();

if (username == SystemParameter.SESSION_USER_NAME)

{

OnlineUserMap online = new OnlineUserMap();

if (online.isLogin(username)

&& online.getSessionId(username).equals(sessionId))

{

online.removeUser(username);

}

}

}

}

4 、過濾器 [ 代碼完全參照“僞代碼”編寫,所以沒寫註釋。 ]

package net.jiakuan.books.webs.filters;

import java.io.IOException ;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import net.jiakuan.books.common.OnlineUserMap;

import net.jiakuan.books.common.SystemParameter;

import net.jiakuan.books.models.Users;

public class LoginFilter implements Filter

{

public void doFilter(ServletRequest arg0, ServletResponse arg1,

FilterChain chain) throws IOException , ServletException

{

HttpServletRequest request = (HttpServletRequest)arg0;

HttpServletResponse response = (HttpServletResponse)arg1;

String fn = request.getParameter("fn" );

if (fn != null && !"" .equals(fn) && !fn.equalsIgnoreCase("login" ))

{

HttpSession session = request.getSession();

Object obj = session.getAttribute(SystemParameter.SESSION_USER_NAME);

if (obj != null )

{

String username = ((Users)obj).getName();

OnlineUserMap online = new OnlineUserMap();

if (online.isLogin(username))

{

if (session.getId().equals(online.getSessionId(username)))

{

chain.doFilter(arg0, arg1);

}

else

{

response.getWriter().print("<script>window.location.href='common/login.jsp'</script>" );

}

}

else

{

response.getWriter().print("<script>window.location.href='common/login.jsp'</script>" );

}

}

else

{

response.getWriter().print("<script>window.location.href='common/login.jsp'</script>" );

}

}

else

{

chain.doFilter(arg0, arg1);

}

}

}

5 Action 裏面的 2 個方法

package net.jiakuan.books.webs.actions;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import net.jiakuan.books.bll.face.IUsersBll;

import net.jiakuan.books.common.OnlineUserMap;

import net.jiakuan.books.common.SystemParameter;

import net.jiakuan.books.models.Users;

import net.jiakuan.books.webs.forms.UsersForm;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

import org.apache.struts.actions.DispatchAction;

public class UserAction extends DispatchAction

{

IUsersBll usersBll;

/***

* 登錄

*/

public ActionForward login(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response)

throws Exception

{

// 1. 得到用戶輸入

UsersForm usersform = (UsersForm)form;

// 2. new 用戶並設值

Users users = new Users();

users.setLoginId(usersform.getUsers().getLoginId());

users.setLoginPwd(usersform.getUsers().getLoginPwd());

// 3. 調用業務邏輯層驗證賬戶的有效性

Users result = this .usersBll.login(users);

if (result != null )

{

// 驗證狀態

if (result.getUserStates().getId() == 1)

{

request.getSession().setAttribute(SystemParameter.SESSION_USER_NAME, result);

// 把當前登錄用戶添加到在線用戶Map

new OnlineUserMap().addOnlineUser(result.getName(), request.getSession().getId());

return mapping.findForward("user" );

}

else

{

return mapping.findForward("error" );

}

}

else

{

return mapping.findForward("error" );

}

}

/***

* 退出登錄

*/

public ActionForward exit(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response)

throws Exception

{

request.getSession().removeAttribute(SystemParameter.SESSION_USER_NAME);

return mapping.findForward("index" );

}

public void setUsersBll(IUsersBll usersBll)

{

this .usersBll = usersBll;

}

}

把核心代碼都貼上來了,限於篇幅其他代碼不在贅述。

如果對代碼中有什麼疑惑,可以通過 [email protected] 找到我。

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