Listener

作者: 每天要吃三个小朋友 | 来源:发表于2017-05-15 20:12 被阅读0次

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"%>  
<html>  
<head>  
<title>主页</title>  
</head>  
<body>  
    在线人数:<h1><%=request.getSession().getAttribute("onlineUserCount") %></h1>  
</body>  
</html>  

例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.*" %>

<html>  
<head>  
<title>在线用户</title>  
</head>  
<body>  
    在线用户:
    <%
    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()){
    %>
    <tr>
        <td><%=rs.getString(1)%>
        <td><%=rs.getString(2)%>
        <td><%=rs.getString(3)%>
        <td><%=rs.getString(4)%>
        <td><%=rs.getString(5)%>
    </tr>
    <%}%>
</body>  
</html>

相关文章

  • Event Emitter

    Tips: 先注册listener - on,后emit Listener function 同步执行 'on' ...

  • 启动和停止Oracle

    配置Oracle listener 启动Oracle 2.1 启动server 2.2 启动listener 停止...

  • 0009.使用环境变量中设定的topic

    topics = {"#{__listener.getTopic()}"},__listener相当于一个伪Bea...

  • 监听

    listener创建方式(1)netca (2)netmgr (3)编辑listener.ora文件 listen...

  • 三、Listener介绍

    使用Listener步骤: 定义Listenner实现类。 通过注解或在web.xml文件配置Listener。 ...

  • Kotlin-委托剖析(1)- 接口委托

    简单列子 定义Listener接口,A、B都实现Listener接口。如果A、B onSuccess\onFail...

  • SpringCloud Stream 集成 rabbitMQ

    配置文件 基础配置 consumer消费者 channel listener队列监听 listener/dlq死信...

  • Listener

    监听器是实现特定的接口的java类,用来监听web应用中ServletContext,ServletRequest...

  • Listener

    Listener与Filter

  • Listener

    Listener的作用是监听web应用(ServletContext对象,即jsp的隐式对象application...

网友评论

      本文标题:Listener

      本文链接:https://www.haomeiwen.com/subject/agehxxtx.html