所谓“单用户单账户登录”是指:在同一系统中,一个用户名不能在两个地方同时登录。
我们参照 QQ 实现效果:
当某账号在 A 处登录后,在未退出的情况下,如果再到 B 处登录,那么,系统会挤下 A 处登录的账号。
先看看伪代码:,因为我会按照这个流程来实现。
基于struts单用户登录
========================
实现效果:
当同一帐号在不同的地点,同时在线登录第二次时,那么此时第一次登录的用户做任何操作都会跳转至指定页面。。。
伪代码:
1. 监听器:(Listener)
监控对session值操作:(让类 实现 HttpSessionAttributeListener 接口)
1.1 当对session赋值时,进行判断:
if( 当前操作中的键 为“登录监听”){
则把该用户加入到在线用户列表中。
}
1.2 当对session的值做移除操作时,进行判断:
if( 当前操作中的键 为“登录监听”){
if(当前用户在在线列表中,并且,列表中的sessionId是否和当前的sessionID相等){
把 当前用户从全局 列表 中移除
}
}
2. 过滤器(Filter)
过滤所有操作:
2.1. 当做过滤操作时,
if( 该操作不为空 ,并且 ,该操作不为空字符串 并且, 该操作是否不为登录 ){
if( session 中 存在标识 “用户名”[因为用户名是不允许重复] ){
if( 在线列表中 存在当前用户 ){
if( 当前的sessionID 和 在线列表中 以当前用户为标识的 sessionID 相等 ){
通过过滤器
} else {
销毁session
直接跳转到指定页面
}
} else {
销毁session
直接跳转到指定页面
}
} else {
直接调转到指定页面
}
} else {
通过过滤器
}
3. 在线用户列表: (public static Map<String ,String>)
类中的属性
3. public static Map<String, String> onlineUser = new HashMap<String, String>();
类中的方法列表:
3.1. 得到在线用户Map
3.2. 添加在线用户
3.3. 得到在线用户的sessionId
3.4. 判断用户是否已经登录
3.5. 移除在线用户
4. 登录Action (LoginAction)
类中的方法列表:
4.1. 用户登录
4.2. 用户退出
环境:
Tomcat 6 , jdk6 , MyEclipse7
Struts1.2+Hibernate+Spring
好,开工:
第一步:搭架子,把 SSH 整合起来。
第二步:编写代码
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;
}
}