监听器的使用
- 在线客户端统计统计的是访问的IP,通过IP去统计访问量,然后再安全退出。
- 首先在建立一个web工程
- 然后创建MyServletContextListener类去实现ServletContextListener接口,在web工程启动时创建对象,创建Map集合,然后把集合对象放到ServletContext域中
- 接着在com.bjpowernode.listeners包下建立MyRequestListener类去实现ServletRequestListener接口,它在浏览器向服务器发出请求时初始化创建请求对象,用sre.getServletRequest()方法去获取request,进而用getRemoteAddr()获取到IP,然后创建session域,再创建Map集合,从Map中获取由当前IP所发出的所有Session组成的List,判断当前的List是否为null.若为null,则创建List,遍历List.若List中存在当前Session对象,则不用操作List
- 执行安全退出操作,创建Session域,使Session失效,让MySessionListener类去实现 HttpSessionListener接口,然后安全退出,具体代码如下
MyServletContextListener类
package com.bjpowernode.listeners;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSession;
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//创建一个Map,key为ip,value为该ip上所发出的会话对象
Map<String,List<HttpSession>> map=new HashMap<>();
//获取ServletContext,即全局域对象
ServletContext sc = sce.getServletContext();
//将map放入到全局域中
sc.setAttribute("map", map);
}
}
MyRequestListener类
package com.bjpowernode.listeners;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class MyRequestListener implements ServletRequestListener {
//将当前Session对象存放到List中
@Override
public void requestInitialized(ServletRequestEvent sre) {
// 获取当前request
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
// 获取当前ip
String clientIp = request.getRemoteAddr();
// 获取当前session对象
HttpSession currentsession = request.getSession();
// 获取全局域
ServletContext sc = sre.getServletContext();
Map<String, List<HttpSession>> map = (Map<String, List<HttpSession>>) sc.getAttribute("map");
//从Map中获取由当前IP所发出的所有Session组成的List
List<HttpSession> sessions = map.get(clientIp);
//判断当前的List是否为null.若为null,则创建List.
if(sessions==null) {
sessions=new ArrayList<>();
}
//遍历List.若List中存在当前Session对象,则不用操作List
for (HttpSession httpSession : sessions) {
if(httpSession==currentsession) {
return;
}
}
//将当前Session放入到这个List
sessions.add(currentsession);
//将变化过的List重新写回到map
map.put(clientIp, sessions);
//将变化过的map重新写回到全局域
sc.setAttribute("map", map);
//将当前ip放入到当前session
currentsession.setAttribute("clientIp",clientIp);
}
}
MySessionListener类
package com.bjpowernode.listeners;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MySessionListener implements HttpSessionListener {
//将当前Session对象从List中删除
@Override
public void sessionDestroyed(HttpSessionEvent se) {
//获取当前Session对象
HttpSession currentSession = se.getSession();
//从当前Session中获取当前ip
String clientIp = (String) currentSession.getAttribute("clientIp");
//获取全局域
ServletContext sc = currentSession.getServletContext();
//从全局域中获取map
Map<String,List<HttpSession>> map=(Map<String, List<HttpSession>>) sc.getAttribute("map");
//从Map中获取List
List<HttpSession> sessions = map.get(clientIp);
//从List中删除当前Session对象
sessions.remove(currentSession);
//若List中没有了元素,则说明当前IP所发出的会话全部关闭,那么就可以从map中将当前ip所对应的Entry对象删除
//若List中仍有元素,则说明当前IP所发出的会话还存在,那么将这个变化过的List写回到map
if(sessions.size()==0) {
map.remove(clientIp);
}else {
map.put(clientIp, sessions);
}
//将变化过的写回到全局域
sc.setAttribute("map", map);
}
}
LogoutServlet 类
package com.bjpowernode.servlets;
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;
public class LogoutServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
if(session!=null) {
session.invalidate();
}
}
}
web.xml注册监听器和跳转到退出
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>12-clientCount</display-name>
<listener>
<listener-class>com.bjpowernode.listeners.MyRequestListener</listener-class>
</listener>
<listener>
<listener-class>com.bjpowernode.listeners.MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>com.bjpowernode.listeners.MySessionListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>LogoutServlet</display-name>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>com.bjpowernode.servlets.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/logoutServlet</url-pattern>
</servlet-mapping>
</web-app>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
您是第${map.size()}位访客。<br>
安全<a href="${pageContext.request.contextPath }/logoutServlet">退出</a>
<br>
<c:forEach items="${map }" var="entry">
${entry.key}=${entry.value.size()}<br>
</c:forEach>
</body>
</html>