一个限制登陆的listener应用

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


<%
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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值