Listener

Listener是Servlet的监听器,可以监听客户端的请求和服务器的操作,并自动激发一些操作,比如监听在线用户数量。常用接口如下

  • ServletContextListener 监听ServletContext的创建与销毁
    当创建时激发contextInitialized(ServletContextEvent sce)
    销毁时激发contextDestroyed(ServletContextEvent sce)
  • ServletContextAttributeListener 监听ServletContext(application)范围内属性的变化
    添加属性时激发attributeAdded(ServletContextAttributeEvent event)
    删除属性时激发attributeRemoved(ServletContextAttributeEvent event)
    替换属性时激发attributeReplaced(ServletContextAttributeEvent event)
  • ServletRequestListener 监听用户request的创建与销毁
    创建时激发requestInitialized(ServletRequestEvent event)
    销毁时激发requestDestroyed(ServletRequestEvent event)
  • ServletRequestAttributeListener 与ServletContextAttributeListener类似,只是监视的是request范围内的属性变化
    attributeAdded(ServletRequestAttributeEvent event)
    attributeRemoved(ServletRequestAttributeEvent event)
    attributeReplaced(ServletRequestAttributeEvent event)
  • HttpSessionListener 监听用户session的创建与销毁
    创建时激发sessionCreated(HttpSessionEvent se)
    销毁时激发sessionDestroyed (HttpSessionEvent se)
  • HttpSessionAttributeListener 与ServletContextAttributeListener类似,只是监视的是session范围内的属性变化
    attributeAdded(HttpSessionBindingEvent se)
    attributeRemoved(HttpSessionBindingEvent se)
    attributeReplaced(HttpSessionBindingEvent se)

例1,统计在线人数,并在ServletContext创建、销毁、修改属性时在控制台打印

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class OnlineUserLitener implements HttpSessionListener,ServletContextListener,ServletContextAttributeListener {

    private long onlineUserCount = 0;

    public long getOnlineUserCount(){
        return onlineUserCount;
    }

    private void toUpdateCount(HttpSessionEvent event){
        event.getSession().setAttribute("onlineUserCount", onlineUserCount);
    }

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        onlineUserCount++;
        toUpdateCount(httpSessionEvent);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        onlineUserCount--;
        toUpdateCount(httpSessionEvent);
    }

    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("Servlet context's " + servletContextAttributeEvent.getName().toString() + "added as " + servletContextAttributeEvent.getValue().toString());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("Servlet context's " + servletContextAttributeEvent.getName().toString() + "removed.");
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("Servlet context's " + servletContextAttributeEvent.getName().toString() + "changed to." + servletContextAttributeEvent.getValue().toString());
    }

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println(servletContextEvent.getServletContext().toString() + "is created");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println(servletContextEvent.getServletContext().toString() + "is destroyed");
    }
}
<%@ page language="java" contentType="text/html; charset=GBK"  
    pageEncoding="GBK"%>  
  
  
主页  
  
  
    在线人数:

<%=request.getSession().getAttribute("onlineUserCount") %>

例2,定义一个ServletRequestListener监听所有用户请求,每当请求达到时,将seesion ID、用户名、用户ip、正在访问的页面、访问时间记录到数据库。启动一条线程,每个一段时间检查一遍,如果某条访问记录的时间与当前时间相差过久,就删掉这条记录(这条线程随应用启动而创建,可以考虑有ServletContextListener实现)

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.sql.ResultSet;
import java.sql.SQLException;

@WebListener
public class RequestListener implements ServletRequestListener{

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {

    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        HttpServletRequest request = (HttpServletRequest) servletRequestEvent.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 resultSet = dd.query("select * from omline_inf where session_id = ?",true, sessionId);
            if (resultSet.next()){
                //更新数据库记录
                resultSet.updateString(4, page);
                resultSet.updateLong(5,System.currentTimeMillis());
                resultSet.updateRow();
                resultSet.close();
            }
            else{
                //这是新用户,将访问信息插入数据库
                dd.insert("insert into online_inf values(?,?,?,?,?)", sessionId, user, ip, page, System.currentTimeMillis());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.ResultSet;

@WebListener
public class OnlineListener implements ServletContextListener{

    //超过该时间后未再次访问,即认为用户离线
    public final int MAX_MILLIS = 10 * 60 * 1000; //10分钟

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //每5秒检查一次
        new javax.swing.Timer(1000 * 5, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try{
                    DbDao dd = new DbDao("com.mysql.jdbc.Driver", "jdbc:mysql://localhost:3306/online_inf", "root", "123456");
                    ResultSet resultSet = dd.query("select * from online_inf", false);
                    StringBuffer toBeRemoved = new StringBuffer("{");//存放需要被删除的session ID
                    //找出需要被删除的session ID
                    while (resultSet.next()){
                        if ((System.currentTimeMillis() - resultSet.getLong(5)) > MAX_MILLIS){
                            toBeRemoved.append("'");
                            toBeRemoved.append(resultSet.getString(1));
                            toBeRemoved.append("',");
                        }
                    }
                    //将这些session ID从数据库中删除
                    if (toBeRemoved.length() > 3){
                        toBeRemoved.setLength(toBeRemoved.length() - 3);
                        toBeRemoved.append("}");
                        dd.modify("delete from online_inf where session_id in " + toBeRemoved.toString());
                    }
                    dd.closeConn();
                }
                catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}
<%@ page language="java" contentType="text/html; charset=GBK", pageEncoding="GBK"%>
<%@ page import="java.sql.*,lee.*" %>

  
  
在线用户  
  
  
    在线用户:
    <%
    DbDao dd = new DbDao("com.sql.jdbc.Driver", "jdbc:mysql://localhost:3306/online_inf", "root", "123456");
    ResultSet rs = dd.query("select * from online_inf", false);
    while(rs.next()){
    %>
    
        <%=rs.getString(1)%>
        <%=rs.getString(2)%>
        <%=rs.getString(3)%>
        <%=rs.getString(4)%>
        <%=rs.getString(5)%>
    
    <%}%>
  

你可能感兴趣的:(Listener)