天天看点

利用Servlet监听器统计在线人数

 监听器的作用是监听web容器的有效事件,它由Servlet空器管理,利用Listener接口监听某个执行程序,并根据该程序的需求做出适应的响应。下面介绍一个应用Servlet监听实现统计在线人数的实例。

整体结构:

利用Servlet监听器统计在线人数

步骤:

(1)创建UserInfoList.java类文件,主要用来存储在线用户和对在线用户进行具体操作:

package com.lixiyu;
import java.util.Vector;
public class UserInfoList {
public static UserInfoList user= new UserInfoList();
@SuppressWarnings("rawtypes")
private Vector vector=null;
/*利用private调用构造函数,
 * 防止被外界产生新的instance对象
 */
@SuppressWarnings("rawtypes")
public UserInfoList(){
    this.vector=new Vector();
}
//外界使用的instance对象
public static UserInfoList getInstance(){
    return user;
}
//增加用户
@SuppressWarnings("unchecked")
public boolean addUserInfo(String user){
    if(user!=null){
        this.vector.add(user);
        return true;
    }else{
        return false;
    }
}
//获取用户列表
@SuppressWarnings("rawtypes")
public Vector getList(){
    return vector;
}
//移除用户
public void removeUserInfo(String user){
    if(user!=null){
        vector.removeElement(user);
    }
}
}      

(2)创建UserInfoTrace.java类文件,主要实现valueBound(HttpSessionBindingEvent arg0)和valueUnbound(HttpSessionBindingEven arg0)两个方法。当有对象加入session时,valueBound()方法会被自动执行;当有对象从session中移除时,valueUnbound()方法会被自动执行,在valueBound()和valueUnbound()方法中都加入了输出信息的功能,可使用户在控制台更清楚地了解执行过程。

利用Servlet监听器统计在线人数

代码:

package com.lixiyu;
import javax.servlet.http.HttpSessionBindingEvent;
public class UserInfoTrace implements javax.servlet.http.HttpSessionBindingListener{
private String user;
private UserInfoList container=UserInfoList.getInstance();
public UserInfoTrace(){
    user="";
}
//设置在线监听人员
public void setUser(String user){
    this.user=user;
}
//获取在线监听
public String getUser(){
    return this.user;
}
@Override
public void valueBound(HttpSessionBindingEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("上线"+this.user);
}
@Override
public void valueUnbound(HttpSessionBindingEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("下线"+this.user);
    if(user!=""){
        container.removeUserInfo(user);
}
}
}      

(3)创建showUser.jsp页面文件,在页面中设置session的setMaxInactiveInterval()为10秒,这样可以缩session的生命周期:

<%@ page contentType="text/html; charset=UTF-8" language="java" import="java.sql.*" errorPage="" %>
<%@ page import="java.util.*"%>
<%@ page import="com.lixiyu.*"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>使用监听查看在线用户</title>
<link href="css/style.css" rel="stylesheet" type="text/css">
</head>
<%
UserInfoList list=UserInfoList.getInstance();
UserInfoTrace ut=new UserInfoTrace();
String name=request.getParameter("user");
ut.setUser(name);
session.setAttribute("list",ut);
list.addUserInfo(ut.getUser());
session.setMaxInactiveInterval(10);
%>
<body>
<div align="center">
<table width="506" height="230" border="0" cellpadding="0" cellspacing="0" background="p_w_picpath/background2.jpg">
  <tr>
    <td align="center"><br><br>
                                                                                                                      
 <textarea rows="8" cols="20">
<%
Vector vector=list.getList();
if(vector!=null&&vector.size()>0){
for(int i=0;i<vector.size();i++){
  out.println(vector.elementAt(i));
}
}
%>
</textarea><br><br>
 <a href="loginOut.jsp">返回</a>
                                                                                                                      
 </td>
  </tr>
</table>
</div>
</body>
</html>      

(4)编写一个过滤器CharactorFilter确保不会乱码,编写MyContentListener实现监听接口并配置web.xml文件映射。

CharactorFilter

package com.lixiyu;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
// 字符编码过滤器
public class CharactorFilter implements Filter {
    // 字符编码
    String encoding = null;
    @Override
    public void destroy() {
        encoding = null;
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // 判断字符编码是否为空
        if(encoding != null){
            // 设置request的编码格式
            request.setCharacterEncoding(encoding);
            // 设置response字符编码
            response.setContentType("text/html; charset="+encoding);
        }
        // 传递给下一过滤器
        chain.doFilter(request, response);
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 获取初始化参数
        encoding = filterConfig.getInitParameter("encoding");
    }
}      

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
  <display-name>web</display-name>
 <!-- 声明过滤器 -->
    <filter>
        <!-- 过滤器名称 -->
        <filter-name>CharactorFilter</filter-name>
        <!-- 过滤器的完整类名 -->
        <filter-class>com.lixiyu.CharactorFilter</filter-class>
        <!-- 初始化参数 -->
        <init-param>
            <!-- 参数名 -->
            <param-name>encoding</param-name>
            <!-- 参数值 -->
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <!-- 过滤器映射 -->
    <filter-mapping>
        <!-- 过滤器名称 -->
        <filter-name>CharactorFilter</filter-name>
        <!-- URL映射 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  <servlet>
    <description>Added by JBuilder to compile JSPs with debug info</description>
    <servlet-name>debugjsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
      <param-name>classdebuginfo</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>debugjsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
  </servlet-mapping>
<listener>
     <listener-class>com.lixiyu.MyContentListener</listener-class>
</listener>
</web-app>      

(5)编写登陆页index.jsp和登出页loginOut.jsp

index.jsp

<%@ page contentType="text/html; charset=UTF-8" language="java" import="java.sql.*" errorPage="" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>使用监听查看在线用户</title>
</head>
<script language="javascript">
function checkEmpty(form){
for(i=0;i<form.length;i++){
if(form.elements[i].value==""){
alert("表单信息不能为空");
return false;
}
}
}
</script>
<link href="css/style.css" rel="stylesheet" type="text/css">
<body>
<div align="center">
  <table width="506" height="170" border="0" cellpadding="0" cellspacing="0" background="p_w_picpath/background1.jpg">
    <tr>
      <td align="center">
        <form name="form" method="post" action="showUser.jsp" onSubmit="return checkEmpty(form)">
    <input type="text" name="user"><br><br>
    <input type="submit" name="Submit" value="登录">
  </form>
                                                                                                     
                                                                                                     
                                                                                                     
      </td>
    </tr>
  </table>
</div>
</body>
</html>      

loginOut.jsp

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<%
         session.invalidate();
 out.println("<script>parent.location.href='index.jsp';</script>");
%>      

最后运行本实例,结果如图所示:

当输入为空会提示:

利用Servlet监听器统计在线人数
利用Servlet监听器统计在线人数