锁定老帖子 主题:基于SSH的单用户单账户登录全过程。
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-07-13
最后修改:2009-07-13
[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; } }
把核心代码都贴上来了,限于篇幅其他代码不在赘述。 如果对代码中有什么疑惑,可以通过 topcss@gmail.com 找到我。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-07-13
不需要基于SSH,基于Servlet足以
|
|
返回顶楼 | |
发表时间:2009-07-13
KimShen 写道 不需要基于SSH,基于Servlet足以
jsp也行,呵呵。 |
|
返回顶楼 | |
发表时间:2009-07-14
貌似太简单的介绍了!如果做出一个基于SSH的例子,着重描述架构的原理和spring的事务配置。
|
|
返回顶楼 | |
发表时间:2009-07-14
yisafe 写道 貌似太简单的介绍了!如果做出一个基于SSH的例子,着重描述架构的原理和spring的事务配置。
第一步:搭架子,把 SSH 整合起来。参照: [url]http://sites.google.com/site/topcss/struts-spring-hibernate-de-ji-cheng [/url] 这里有Spring的配置 |
|
返回顶楼 | |
发表时间:2009-07-19
引用 zouguibao 发送至 我 显示详细信息 7月16日 (3 天前) 回复 您好:topcss 在javaeye论坛里您发表主题为“基于SSH的单用户单帐户登录全过程”的帖子,我仔细看了,有些细节不是很明白,向你请教一下。过滤器中的String fn = request.getParameter("fn");中的fn参数从哪里获取来的,有什么作用?还有您的action中的result.getUserStates().getId() == 1中的getUserStates().getId()是什么呢?字段吗?有什么作用?如果可能的话,可以把整个项目发给我吗? 期待您的回复。 前两天网络出问题了,刚才才上起网。 1.String fn = request.getParameter("fn");中的fn参数从哪里获取来的? 答: 是在struts-config.xml文件中配置的,他用来得到方法名,如: 我们的jsp页面中有这么一个form, <form action="user.do" method="post"> <input type="hidden" name="fn" value="login" /> </form> 其功能为用户登录[value="login"],而用户类中有多个方法。[注册,退出等...] 2.action中的result.getUserStates().getId() == 1中的getUserStates().getId()是什么呢? 答: 这里,由于用户登录时需要判断用户的状态是否正常,故,写了“result.getUserStates().getId() == 1”句代码 至于项目,只是没事时随便写了一个例子而已,当时没有保存下来,确实不好意思... |
|
返回顶楼 | |
发表时间:2009-07-20
就是session里的id判断和地址对比
|
|
返回顶楼 | |
浏览 9521 次