jackyrong

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

    下面是学习时,发现书上有段不错的代码,是说只允许一台机器的一个帐号登陆的,另外一个上线的话,会被注销掉。下面是代码;

 

<%
 String action = request.getParameter("action");
 String account = request.getParameter("account");

 if("login".equals(action) && account.trim().length() > 0){
 
  // 登录,将personInfo放入session
  PersonInfo personInfo = new PersonInfo();
  personInfo.setAccount(account.trim().toLowerCase());
  personInfo.setIp(request.getRemoteAddr());
  personInfo.setLoginDate(new java.util.Date());
  
  session.setAttribute("personInfo", personInfo);
  
  response.sendRedirect(response.encodeRedirectURL(request.getRequestURI()));
  return;
 }
 else if("logout".equals(action)){
 
  // 注销,将personInfo从session中移除
  session.removeAttribute("personInfo");
  
  response.sendRedirect(response.encodeRedirectURL(request.getRequestURI()));
  return;
 }
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Insert title here</title>
  <style type="text/css">
  body {
   font-size:12px;
  }
  </style>
 </head>
 <body>
  
  <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>

 

PersonInfo.java:

 

public class PersonInfo implements Serializable {

 private static final long serialVersionUID = 4063725584941336123L;

 // 帐号
 private String account;

 // 登录IP地址
 private String ip;

 // 登录时间
 private Date loginDate;

 public String getAccount() {
  return account;
 }

 public void setAccount(String account) {
  this.account = account;
 }

 public String getIp() {
  return ip;
 }

 public void setIp(String ip) {
  this.ip = ip;
 }

 public Date getLoginDate() {
  return loginDate;
 }

 public void setLoginDate(Date loginDate) {
  this.loginDate = loginDate;
 }

 @Override
 public boolean equals(Object obj) {
  if (obj == null || !(obj instanceof PersonInfo)) {
   return false;
  }
  return account.equalsIgnoreCase(((PersonInfo) obj).getAccount());
 }

 

listener.java:用MAP把登陆的session保存

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());
  }

 }

 

  还有一个小技巧就是:

MyContextListener implements ServletContextListener {

 

 

public void contextInitialized(ServletContextEvent event) {
  // 启动时,记录服务器启动时间
  ApplicationConstants.START_DATE = new Date();
 }

 public void contextDestroyed(ServletContextEvent event) {
  // 关闭时,将结果清除。也可以将结果保存到硬盘上。

}

  ServletContextListener :监听context的创建与销毁的,当服务器启动或执行war包时,执行contextInitialized,关闭时执行
contextDestroyed

posted on 2010-03-04 22:51  jackyrong的世界  阅读(1736)  评论(0编辑  收藏  举报