下面是学习时,发现书上有段不错的代码,是说只允许一台机器的一个帐号登陆的,另外一个上线的话,会被注销掉。下面是代码;
<%
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
分享到:
相关推荐
Servlet中的八大Listener.docServlet中的八大Listener.docServlet中的八大Listener.docServlet中的八大Listener.docServlet中的八大Listener.docServlet中的八大Listener.docServlet中的八大Listener.docServlet中的...
Listener单点登录与显示在线用户
简单的例子,通过TcpClient TcpListener 实现Socket 编程,
java jsp listener小用法,记录登录次数。
TcpClient TcpListener Demo 案例 TcpClient TcpListener Demo 案例 TcpClient TcpListener Demo 案例 TcpClient TcpListener Demo 案例 QQ:574311505
1.创建一个类实现 ServletContextListener (具体实现哪个Listener根据情况来判断) 2.在类上加入注解 @WebListener 3.重写 contextInitialized() 与 contextDestroyed() 方法 4.编写启动类 5.增加注解 @...
杂记(一):Listener、Filter和工具 杂记(一):Listener、Filter和工具
TcpListener 监听服务端,可实现多客户端连接
基于LUA的wireshark插件,利用listener搭建一个对esp协议包的包序号连续性检验的提示器
listener监听器小例子
mac_Listener
Android Listener侦听的N种写法
用户的一个操作,如点击一个按钮、调用一个方法、创建一个对象等。 产生事件的对象。 负责监听发生在 事件源上的事件。 监听器的成员方法,当事件发生的时候会触发对应的处理器(成员方法)。 Listener监听器 事件...
ORA-12541 TNSno listener 的解决方案 ORA-12541 TNSno listener 的解决方案
在Unity中用 TcpClient、TcpListener 两个封装类和 NetworkStream 来实现一个简单的网络通讯 demo 实现原理 1、首先通过 IP 和 端口号,开启服务器监听 2、在客户端连接进入之后,会开启一个线程维持与该客户端的...
c# tcplistener tcp 监控
C# TcpListener/TcpClient Demo
MQListener Demo
listener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsname
一个学习C#的TcpListener例程!