`
jiahh
  • 浏览: 37467 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

一个限制登陆的listener应用

    博客分类:
  • web
 
阅读更多
   下面是学习时,发现书上有段不错的代码,是说只允许一台机器的一个帐号登陆的,另外一个上线的话,会被注销掉。下面是代码;



<%
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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics