单态登录是什么?
你可以这个样子理解吧,比如你再你的手机上登录了 你的王者荣耀账号,然后又换另一部手机进行登录,这样,你之前登录的就会被顶掉。
做单态登录,本人使用的是Me,你需要用的Jar包是commons-loggin.jar,版本随便一个都可以
来来来,先看一看有啥
,来来来,上代码,先是JSP的
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:directive.page import="com.openlab.listener.PersonInfo" />
<%
String action = request.getParameter("action");
String account = request.getParameter("account");
if("login".equals(action) && account.trim().length()>0){
PersonInfo personInfo = new PersonInfo();
personInfo.setAccount(account);
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)){
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>
</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"/><br/>
<a href="${pageContext.request.requestURI}?action=logout">退出</a>
<!-- 每五秒钟刷新一次页面 -->
<script>setTimeout("location=location;", 5000);</script>
</c:when>
<c:otherwise>
<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>
</body>
</html>
然后是
package com.openlab.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;
public class LoginListener implements HttpSessionAttributeListener {
Log log= LogFactory.getLog(this.getClass());
Map<String,HttpSession> map = new HashMap<String,HttpSession>();
public LoginListener() {
// TODO Auto-generated constructor stub
}
public void attributeRemoved(HttpSessionBindingEvent event) {
// 删除属性前被调用
String name = event.getName();
if(name.equals("personInfo")){
PersonInfo personInfo = (PersonInfo) event.getValue();
map.remove(personInfo.getAccount());
log.info("账号"+personInfo.getAccount()+"注销");
}
}
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){
HttpSession session = map.get(personInfo.getAccount());
PersonInfo oldPersonInfo = (PersonInfo) session.getAttribute("personInfo");
log.info("账号"+oldPersonInfo.getAccount()+"在"+oldPersonInfo.getIp()+"已经登录,该登录将被迫下线!");
session.removeAttribute("personInfo");
session.setAttribute("msg", "您的账号已经在其他机器上登录,您被迫下线!");
}
map.put(personInfo.getAccount(), event.getSession());
log.info("账号"+personInfo.getAccount()+"在"+personInfo.getIp()+"登录");
}
}
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){
HttpSession session = map.get(personInfo.getAccount());
session.removeAttribute("personInfo");
session.setAttribute("msg", "您的账号已经在其他机器上登录,您被迫下线!");
}
map.put(personInfo.getAccount(), event.getSession());
log.info("账号"+personInfo.getAccount()+"在"+personInfo.getIp()+"登录");
}
}
}
package com.openlab.listener;
import java.io.Serializable;
import java.util.Date;
public class PersonInfo implements Serializable{
private static final long serialVersionUID = 1L;
private String account;
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;
}
public boolean equals(Object obj){
if(obj == null || !(obj instanceof PersonInfo)){
return false;
}
return account.equalsIgnoreCase(((PersonInfo) obj).getAccount());
}
}
运行跳转页面的时候要是出现
$%7BpageContext.request.requestURI%7D 这种情况
这是因为你的web-app的版本过低,你只需要把web.xml里面的version="2.5"改成 2.5以上的就好