java监听器实现单点登录
java监听器实现单点登录
package Listener;
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;
/**
* Application Lifecycle Listener implementation class LoginSessionListener
*
*/
public class LoginSessionListener implements HttpSessionAttributeListener {
Log log =LogFactory.getLog(this.getClass());//日志记录
Map<String,HttpSession> map=new HashMap<String,HttpSession>();//保存session
/**
* Default constructor.
*/
public LoginSessionListener() {
// TODO Auto-generated constructor stub
}
/**
* @see HttpSessionAttributeListener#attributeAdded(HttpSessionBindingEvent)
*/
public void attributeAdded(HttpSessionBindingEvent event) {
//添加session属性时被调用
String name=event.getName();//新建属性名称
if(name.equals("personInfo")){ //登录
PersonInfo personInfo=(PersonInfo)event.getValue();
if(map.get(personInfo.getAccount())!=null){
//若map中存在该帐号
//map中有记录,表明该帐号在其他机器上登陆过,将以前的登录失效
HttpSession session =map.get(personInfo.getAccount());
//帐号所属session
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()+"登录");
}
}
/**
* @see HttpSessionAttributeListener#attributeRemoved(HttpSessionBindingEvent)
*/
public void attributeRemoved(HttpSessionBindingEvent event) {
//删除属性前被调用
String name=event.getName();//被删除的属性
if(name.equals("personInfo")){//注销
PersonInfo personInfo = (PersonInfo)event.getValue();
//被移除的PersonInfo
map.remove(personInfo.getAccount());//从map中删除
log.info("帐号"+personInfo.getAccount()+"注销");
}
}
/**
* @see HttpSessionAttributeListener#attributeReplaced(HttpSessionBindingEvent)
*/
public void attributeReplaced(HttpSessionBindingEvent event) {
//修改属性时被调用
String name=event.getName();//被修改的属性名
if(name.equals("personInfo")){//没有注销的情况下用另一个帐号登录
PersonInfo oldPersonInfo=(PersonInfo)event.getValue();
//移除旧的登录信息
map.remove(oldPersonInfo.getAccount());//删除map中的旧记录
//新的鞥路信息
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.getAccount(), event.getSession());
}
}
}
web.xml
<listener>
<listener-class>Listener.LoginSessionListener</listener-class>
</listener>
loginServlet
package com.servlet3.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import Listener.PersonInfo;
/**
* Servlet implementation class Login
*/
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Login() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String action =request.getParameter("action");
if("login".equals(action)){
String account=request.getParameter("account");
//如果为login
PersonInfo personInfo=new PersonInfo();
//登录 将personInfo放入session
personInfo.setAccount(account.trim().toLowerCase());//保存帐号
personInfo.setIp(request.getRemoteAddr());//保存IP地址
personInfo.setLoginDate(new java.util.Date());//保存登录时间
session.setAttribute("personInfo", personInfo);
request.getRequestDispatcher("WEB-INF/listener/singleton.jsp").forward(request, response);
return;
}else if("loginout".equals(action)){
session.removeAttribute("personInfo");
//注销,将personInfo从session中移除
request.getRequestDispatcher("WEB-INF/listener/singleton.jsp").forward(request, response);
return;
}
}
}
页面
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="java.util.*,Listener.PersonInfo"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!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=ISO-8859-1">
<title>Insert title here</title>
</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="/Servlet3.0/Login?action=loginoutaccount=${personInfo.account }">退出</a>
<script>setTimeout("location=location;",5000)</script>
</c:when>
<c:otherwise>
${msg }
<c:remove var="msg" scope="session"/>
<form action="/Servlet3.0/Login?action=login" method="post">
帐号:<input name="account">
<input type="submit" value="登录">
</form>
</c:otherwise>
</c:choose>
</body>
</html>

浙公网安备 33010602011771号