第七章 监听器listener单态登录使用案例学习心得
2013-06-09 10:39
459 查看
前言:这个是我自己的学习笔记,用于加深自己对于java web 理解。
单态登录,一个账号只可以在一台机器上登录(浏览器),如果在其他机器上登录了,则原来的登录自动失效。单台登录的目的是防止多台机器同时使用一个账号。
书上P205用的案例是使用一个简单的JSP页面来模拟登录情况。
自我总结:
理解书上的这个案例我自我的总结是:
1.Session对于每一个来访者都会产生一个session对象。
2.书上用的监听器可以监听到所用用户的session。
3.JSP页面是通过session中的personInfo是否有这个的值是否为null,显示页面的。只要认识到session中有个属性可以控制页面的显示。personInfo具体内容可以先不知道。
4.Listener会监听每个新增的session,看session中的personInfo中的账号信息是否有重复的,如果有,就把原来的session中的提到的3中某个属性变为null。
5.结合1和3,如果有账号重复登录的话,先登录的session的某个值就是空,那么它的页面就会跳转到登录的页面。
JSP页面学习:
<% String action =request.getParameter("action"); String account =request.getParameter("account"); if("login".equals(action.toLowerCase())&&account.trim().length()>0) { PersonInfo ref_PersonInfo=new PersonInfo(); ref_PersonInfo.setAccount(account.trim().toLowerCase()); ref_PersonInfo.setIp(request.getRemoteAddr()); ref_PersonInfo.setLoginDate(new java.util.Date()); session.setAttribute("personInfo",ref_PersonInfo); response.sendRedirect(response.encodeRedirectUrl(request.getRequestURI())); return; }else if("logout".equals(action)){ session.removeAttribute("persionInfo"); response.sendRedirect(response.encodeRedirectURL(request.getRequestURI())); return; } %>这部分代码是jsp页面的最先开始执行的可以判断用户是否执行登录或者注销操作。如果执行最后都会执行return语句,就不会显示下面的jsp代码部分了。
<c:choose> <c:when test="${ personInfo != null }"> <!-- 已经登录,将显示帐号信息 --> 欢迎您,${ personInfo.account }。<br/> 您的登录IP为${ personInfo.ip },<br/> 登录时间为<fmt:formatDate value="${ personInfo.loginDate }" pattern="yyyy-MM-dd HH:mm"/>。 <a href="${ pageContext.request.requestURI }?action=logout">退出</a> <!-- 每5秒钟刷新一次页面 --> <script>setTimeout("location=location; ", 5000); </script> </c:when> <c:otherwise> <!-- 没有登录,将显示登录页面 --> ${ msg } <c:remove var="msg" scope="session" /> <form action="${ pageContext.request.requestURI }?action=login" method="post"> 帐号: <input name="account" /> <input type="submit" value="登录"> </form> </c:otherwise> </c:choose>这部分代码就是根据session中是否有 personInfo 属性,决定显示的具体页面是什么!请注意这几个式子${ personInfo != null },${ msg } 这个是EL表达式,可以找到session中的相关属性,其中 ${ msg } msg是在监听器中设置的消息。具体页面只用两种:登录页面和没有登录页面,判断标准是"${ personInfo != null }"。如果你是登录状态你的personInfo不为空null,如果有人修改了你的session,让你personInfo,页面每5秒钟刷新一次<script>setTimeout("location=location; ", 5000); </script>,那么就会显示没有登录页面。具体的修改session的状态是Listener中实现的。
package com.helloweenvsfei.singleton; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class LoginSessionListener implements HttpSessionAttributeListener { Log log = LogFactory.getLog(this.getClass()); Map<String, HttpSession> map = new HashMap<String, HttpSession>(); public void attributeAdded(HttpSessionBindingEvent event) { String name = event.getName(); // 登录 if (name.equals("personInfo")) { PersonInfo personInfo = (PersonInfo) event.getValue(); if (map.get(personInfo.getAccount()) != null) { // map 中有记录,表明该帐号在其他机器上登录过,将以前的登录失效 HttpSession session = map.get(personInfo.getAccount()); PersonInfo oldPersonInfo = (PersonInfo) session .getAttribute("personInfo"); log.info("帐号" + oldPersonInfo.getAccount() + "在" + oldPersonInfo.getIp() + "已经登录,该登录将被迫下线。"); session.removeAttribute("personInfo"); session.setAttribute("msg", "您的帐号已经在其他机器上登录,您被迫下线。"); } // 将session以用户名为索引,放入map中 map.put(personInfo.getAccount(), event.getSession()); log.info("帐号" + personInfo.getAccount() + "在" + personInfo.getIp() + "登录。"); } } public void attributeRemoved(HttpSessionBindingEvent event) { String name = event.getName(); // 注销 if (name.equals("personInfo")) { // 将该session从map中移除 PersonInfo personInfo = (PersonInfo) event.getValue(); map.remove(personInfo.getAccount()); log.info("帐号" + personInfo.getAccount() + "注销。"); } } public void attributeReplaced(HttpSessionBindingEvent event) { String name = event.getName(); // 没有注销的情况下,用另一个帐号登录 if (name.equals("personInfo")) { // 移除旧的的登录信息 PersonInfo oldPersonInfo = (PersonInfo) event.getValue(); map.remove(oldPersonInfo.getAccount()); // 新的登录信息 PersonInfo personInfo = (PersonInfo) event.getSession() .getAttribute("personInfo"); // 也要检查新登录的帐号是否在别的机器上登录过 if (map.get(personInfo.getAccount()) != null) { // map 中有记录,表明该帐号在其他机器上登录过,将以前的登录失效 HttpSession session = map.get(personInfo.getAccount()); session.removeAttribute("personInfo"); session.setAttribute("msg", "您的帐号已经在其他机器上登录,您被迫下线。"); } map.put("personInfo", event.getSession()); } } }LoginSessionListener 源代码
源代码中有一个非常重要的数据结构为Map<String, HttpSession> map = new HashMap<String, HttpSession>();这个数据结构保存了所有的账户和session的对应关系,一旦jsp中的session添加了personInfo,都会调用 public void attributeAdded(HttpSessionBindingEvent event) {...}方法,会在map中查找账户是否已经有了对应的session,如果已经有了,那么就把查找到的session中personInfo移除,这个时候前台的jsp页面每5秒刷新一次,发现personInfo为空就会显示为未登录页面。请注意里面有这个语句:session.setAttribute("msg", "您的帐号已经在其他机器上登录,您被迫下线。");这个时候JSP页面就会通过EL表达式${msg}读到这条消息了。 public void attributeRemoved(HttpSessionBindingEvent event) 方法当session中的personInfo设置为空时,会触发这个方法,他会把相应的session从map中移除。 菜包子 2013年6月9日10:30:13 于马甸桥东
相关文章推荐
- 第七章 监听器listener显示在线用户案例学习心得
- 深入学习JavaWeb中监听器(Listener)的使用方法
- spring心得2--bean的生命周期@Spring监听器的作用@Spring初始化容器案例分析@web项目使用
- Servlet3.0学习总结(四)——使用注解标注监听器(Listener)
- spring心得2--bean的生命周期@Spring监听器的作用@Spring初始化容器案例分析@web项目使用
- Servlet3.0学习总结(四)——使用注解标注监听器(Listener)
- Servlet3.0学习总结(四)——使用注解标注监听器(Listener)
- Servlet3.0学习总结(四)——使用注解标注监听器(Listener)
- Listener学习笔记-- day01 监听器的使用
- 【附】使用监听器ServletContextListener实现网站登录人数统计,可以实现重启服务器后记录仍然存在
- 【Java EE 学习 21 上】【其它类型的监听器】【使用HttpSessionActivationListener监听session的活化和钝化】
- spring心得2--bean的生命周期@Spring监听器的作用@Spring初始化容器案例分析@web项目使用
- Servlet3.0学习总结(四)——使用注解标注监听器(Listener)
- 第七章监听器Listener--八种不同的Listener学习笔记
- 快速学习JavaWeb中监听器(Listener)的使用方法
- Winform下的地图开发控件(GMap.NET)使用心得转载学习
- pyqt 学习基础 4 - creater的一点使用心得
- es 学习 5 DSL mapping 使用 案例
- 使用成员资格和用户登录创建网站--学习笔记
- AJAX的初级使用及登录注册案例