Web Listener --- 精确地监控在线用户的状态
2016-03-29 21:07
393 查看
使用Web Listener 需要两个步骤;
1.定义Listener 实现类2.通过注解或 在web.xml文件配置
一 采用的web事件监听器接口有如下:
1.ServletContextListener :用于web应用的启动与关闭
方法:--public void contextInitialized(ServletContextEvent sce) 启动web时调用
--public void contextDestroyed(ServletContextEvent sce)
2.ServletContextAttributeListener : 用于监听ServletContext(application)范围内属性的变化
--public void attributeAdded(ServletContextAttributeEvent scae)--public void attributeRemoved(ServletContextAttributeEvent scae)
--public void attributeReplaced(ServletContextAttributeEvent scae)
3.ServletRequestListener :用于用户请求
--public void contextInitialized(ServletRequestEvent sce)--public void contextDestroyed(ServletRequestEvent sresce)
4.ServletRequestAttributeListener
--public void attributeRmoved(ServletRequestAttributeEvent srae)--public void attributeRemoved(ServletRequestAttributeEvent srae)
--public void attributeReplaced(ServletRequestAttributeEvent srae)
5.HttpSessionListener
--public void sessionCreate(HttpsessionEvent hse)--public void sessionDestroyed(HttpsessionEvent hse)
6.HttpSessionAttributeListener
--public void attributeRmoved(ServletSessionAttributeEvent ssae)--public void attributeRemoved(ServletSessionAttributeEvent ssae)
--public void attributeReplaced(ServletSessionAttributeEvent ssae)
二 应用--- 更精确地监听在线用户的状态
思路:
1.定义ServletRequestListener,负责监听每个用户请求,当用户的请求到达时,如果是新的会话,将记录(sessionId、用户名、用户IP、正在访问的资源、访问时间)保存下来(插入数据库);如果是老的用户会话则更新记录;
2.启动后台线程,每隔一段时间检查上面的记录,设定离线时间,如果是离线则删除。线程使用ServletContextListener ;
RequestListener.java 代码@WebListener
public class RequestListener implements ServletRequestListener {
// 当用户请求到达、被初始化时触发该方法
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre
.getServletRequest();
HttpSession session = request.getSession();
// 获取session ID
String sessionId = session.getId();
// 获取访问的IP和正在访问的页面
String ip = request.getRemoteAddr();
String page = request.getRequestURI();
String user = (String) session.getAttribute("user");
// 未登录用户当游客处理
user = (user == null) ? "游客" : user;
try {
DbDao dd = new DbDao("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/online_inf", "root", "123456");
ResultSet rs = dd.query(
"select * from online_inf where session_id=?", true,
sessionId);
// 如果该用户对应的session ID存在,表明是旧的会话
if (rs.next()) {
// 更新记录
rs.updateString(4, page);
rs.updateLong(5, System.currentTimeMillis());
rs.updateRow();
rs.close();
} else {
// 插入该用户的在线信息
dd.insert("insert into online_inf values(? , ? , ? , ? , ?)",
sessionId, user, ip, page, System.currentTimeMillis());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
// 当用户请求结束、被销毁时触发该方法
public void requestDestroyed(ServletRequestEvent sre) {
}
}
OnlineListener.java 代码:
@WebListener
public class OnlineListener implements ServletContextListener {
// 超过该时间(10分钟)没有访问本站即认为用户已经离线
public final int MAX_MILLIS = 5 * 60 * 1000;
// 应用启动时触发该方法
public void contextInitialized(ServletContextEvent sce) {
// 每10秒检查一次
new javax.swing.Timer(1000 * 10, new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
DbDao dd = new DbDao("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/online_inf", "root",
"123456");
ResultSet rs = dd.query("select * from online_inf", false);
StringBuffer beRemove = new StringBuffer("(");
while (rs.next()) {
// 如果距离上次访问时间超过了指定时间
if ((System.currentTimeMillis() - rs.getLong(5)) > MAX_MILLIS) {
// 将需要被删除的session ID添加进来
beRemove.append("'");
beRemove.append(rs.getString(1));
beRemove.append("' , ");
}
}
// 有需要删除的记录
if (beRemove.length() > 3) {
beRemove.setLength(beRemove.length() - 3);
beRemove.append(")");
// 删除所有“超过指定时间未重新请求的记录”
dd.modify("delete from online_inf where session_id in "
+ beRemove.toString());
}
dd.closeConn();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
}
public void contextDestroyed(ServletContextEvent sce) {
}
}
在线监听用户的状态 online.jsp
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<%@ page import="java.sql.*,com.yd.dao.DbDao" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> 用户在线信息 </title>
</head>
<body>
在线用户:
<table width="640" border="1">
<%
DbDao dd = new DbDao("com.mysql.jdbc.Driver"
, "jdbc:mysql://localhost:3306/online_inf"
, "root"
, "123456");
// 查询online_inf表(在线用户表)的全部记录
ResultSet rs = dd.query("select * from online_inf" , false);
while (rs.next())
{%>
<tr>
<td><%=rs.getString(1)%>
<td><%=rs.getString(2)%>
<td><%=rs.getString(3)%>
<td><%=rs.getString(4)%>
</tr>
<%}%>
</body>
</html>
注:本人不喜欢直接在jsp页面查询数据库,因临时所写
online_inf.sql 语句:
drop database online_inf;
create database online_inf;
use online_inf;
create table online_inf
(
session_id varchar(255) primary key,
username varchar(255),
user_ip varchar(255),
access_res varchar(255),
last_access bigint
);
最后感叹下,打字的速度需要练练.....
相关文章推荐
- openCV vs2013配置
- Linux下查看和添加PATH环境变量
- linux 内存管理分析之-----SLAB层
- [译]zookpeer 入门教程
- 《Linux内核设计与实现》学习总结 Chap3
- Linux-HA开源软件Heartbeat(概念篇)
- 《Linux内核设计与实现》学习总结 Chap18
- centos启动时间查看
- 日常运维工作中如何确保你的linux操作系统安全
- 【opencv】光流法
- VMware安装CentOS遇到Intel vt-x处于禁止状态
- VMware安装CentOS遇到Intel vt-x处于禁止状态
- 基于qt的嵌入式Linux开发环境搭建
- docker私有仓库搭建(ubuntu 14.04和centos7)
- linux动态库编译和使用详细剖析
- Hadoop从入门到上手工作视频
- 安装cactiez v11对windows和linux系统进行监控
- 安装cactiez v11对windows和linux系统进行监控
- win10 VMware NAT方式 centOS 6.7 配置静态IP
- Dockerfile学习(一)