您的位置:首页 > 运维架构

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

);

最后感叹下,打字的速度需要练练.....
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: