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>

  

 

posted @ 2017-01-06 13:23  fliay  阅读(265)  评论(0)    收藏  举报