监听器

来源:互联网 发布:ubuntu安装datautil 编辑:程序博客网 时间:2024/06/07 16:00

监听器

web的事件编程

  • 事件源: ServletContext对象,ServletRequest对象,HttpSession对象(域对象)
  • 事件: ServletContextEvent,ServletRequestEvent,xxx(创建或销毁对象,对象的属性修改)
  • 事件监听器(接口): ServletContextListener,ServletRequestListener …

web监听器:是一些实现了特定接口的java程序,用于监听web开发中常用的对象(ServletContext对象,ServletRequest对象,HttpSession对象)的创建和销毁行为,以及这些对象的属性修改行为(setAttribute,removeAttribute)

事件源 事件对象 web监听器 ServletContext对象 ServletContextEvent(创建和销毁) ServletContextListener接口 ServletContext对象的属性 ServletContextAttributeEvent(增加,修改,删除) ServletContextAttributeListener接口 ServletRequest对象 ServletRequestEvent(创建和销毁) ServletRequestListener接口 ServletRequest对象的属性 ServletRequestAttributeEvent(增加,修改,删除) ServletRequestAttributeListener接口 HttpSession对象 HttpSessionEvent(创建和销毁) HttpSessionListener接口 HttpSession对象的属性 HttpSessionBindingEvent(增加,修改,删除) HttpSessionAttributeListener接口

ServletContextListener

用于监听ServletContext对象的创建和销毁行为

ServletContext对象

  • 创建:加载当前的web项目的时候
  • 销毁:关闭服务器或者重新部署web项目

例子:初始化时创建表,销毁时清除表

mysql-connector驱动包—用于连接mysql
c3p0包—数据库连接池
commons-dbutils—对数据库的二次封装简化

c3p0-config.xml配置文件,配置信息如下:

<c3p0-config>  <!-- 使用默认的配置读取连接池对象 -->  <default-config>    <!--  连接参数 -->    <property name="driverClass">com.mysql.jdbc.Driver</property>    <property name="jdbcUrl">jdbc:mysql://localhost:3306/day21</property>    <property name="user">root</property>    <property name="password">123</property>    <!-- 连接池参数 -->    <property name="initialPoolSize">5</property>    <property name="maxPoolSize">8</property>    <property name="checkoutTimeout">3000</property>  </default-config></c3p0-config>

JdbcUtil 工具类用于获得数据库连接池,这里使用单例模式
数据库连接池采用单例模式的原因:
数据库连接是一种数据库资源。软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗, 当然,使用数据库连接池还有很多其它的好处,可以屏蔽不同数据数据库之间的差异,实现系统对数据库的低度耦合,也可以被多个系统同时使用,具有高可复用性,还能方便对数据库连接的管理等等。数据库连接池属于重量级资源,一个应用中只需要保留一份即可,既节省了资源又方便管理。所以数据库连接池采用单例模式进行设计会是一个非常好的选择。

import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class JdbcUtil {    private JdbcUtil() {    }    private static ComboPooledDataSource ds = new ComboPooledDataSource();    //用于获得数据库连接池的数据源    public static DataSource getDataSource() {        return ds;    }}

dao层的编写,创建表以及清除表

import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;public class SystemDao {    // 初始化表(创建表)    public void initTable() {        QueryRunner qr = new QueryRunner(JdbcUtil.getDataSource());        try {            qr.update("create table student(id int primary key,name varchar(20),gender varchar(20))");        } catch (SQLException e) {            e.printStackTrace();            throw new RuntimeException(e);        }    }    // 清除表    public void clearTable() {        QueryRunner qr = new QueryRunner(JdbcUtil.getDataSource());        try {            qr.update("drop table student");        } catch (SQLException e) {            e.printStackTrace();            throw new RuntimeException(e);        }    }}

核心:自定义监听器的编写,需要实现响应的接口

import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;//需求:1在启动的时候,初始化表;2在项目结束的时候,删除表public class MyContextListener implements ServletContextListener {    SystemDao dao = new SystemDao();    @Override    public void contextInitialized(ServletContextEvent sce) {        // System.out.println("Context对象创建");        // 初始表        dao.initTable();        System.out.println("初始成功");    }    @Override    public void contextDestroyed(ServletContextEvent sce) {        // System.out.println("Context对象销毁");        dao.clearTable();        System.out.println("清除成功");    }}
<!-- web.xml中注册监听器 --><listener>    <listener-class>cn.itcast.context.MyContextListener</listener-class></listener>

ServletContextAttributeListener

ServletContextAttributeListener用于监听ServletContext对象的属性操作(增加属性,修改属性,删除属性)

  • 增加属性: setAttribute(name,Object); 第一次就是增加属性
  • 修改属性: setAttribute(name,Object); 如果前面有增加了同名的属性,则修改。
  • 删除属性: removeAttribute(name);

首先我们创建一个context.jsp,编写脚本用来实现增加修改删除属性的操作

 <%        application.setAttribute("name", "james");   //增加        application.setAttribute("name", "wesbrook");//修改        application.removeAttribute("name");//刪除 %>

然后我们对先前的MyContextListener类之后实现ServletContextAttributeListener,此时会出现三个需要实现的方法
这样就可以对属性的相关操作得到监听的作用

@Override    public void attributeAdded(ServletContextAttributeEvent event) {        // System.out.println("属性增加");        // 得到属性名        String name = event.getName();        // 得到属性值        Object value = event.getValue();        System.out.println("属性增加:" + name + "=" + value);    }    @Override    public void attributeReplaced(ServletContextAttributeEvent event) {        // System.out.println("属性修改");        // 得到属性名        String name = event.getName();        // 得到修改前的属性值        // Object value = event.getValue();        // 得到修改后的属性值,需要从ServletContext事件源对象再次获取属性,才可以得到最新的属性值        ServletContext servletContext = event.getServletContext();        Object value = servletContext.getAttribute(name);        System.out.println("属性修改:" + name + "=" + value);    }    @Override    public void attributeRemoved(ServletContextAttributeEvent event) {        // System.out.println("属性删除");        // 得到属性名        String name = event.getName();        // 得到属性值        Object value = event.getValue();        System.out.println("属性删除:" + name + "=" + value);    }

ServletRequestListener

ServletRequestListener用于监听ServletRequest对象的创建和销毁。
ServletRequest对象:封装请求信息

  • 创建:每次发出请求时
  • 销毁:请求完毕后

例子:监听一个网页请求,并获得客户的ip,打印在界面上

MyRequestListener的编写,实现ServletRequestListener接口

import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;public class MyRequestListener implements ServletRequestListener {    @Override    public void requestInitialized(ServletRequestEvent sre) {        // System.out.println("一个请求被创建了");        // 得到请求相关的信息        HttpServletRequest request = (HttpServletRequest) sre                .getServletRequest();        // 得到客户的ip        String ip = request.getRemoteHost();        // 共享数据到页面中        HttpSession session = request.getSession();        session.setAttribute("ip", ip);    }    @Override    public void requestDestroyed(ServletRequestEvent sre) {        System.out.println("一个请求对象被销毁了");    }}

web.xml中注册监听器

<listener>    <listener-class>cn.itcast.request.MyRequestListener</listener-class></listener>

request.jsp页面的编写

 <body>    客户的ip地址是 ${sessionScope.ip } </body>

ServletRequestAttributeListener

ServletRequestAttributeListener用于监听ServletRequest属性操作

  • 增加属性: setAttribute(name,Object); 第一次就是增加属性
  • 修改属性: setAttribute(name,Object); 如果前面有增加了同名的属性,则修改
  • 删除属性: removeAttribute(name);

代码与ServletContextAttributeListener类似,不再赘述

HttpSessionListener

HttpSessionListener用于监听HttpSession对象的创建和销毁
HttpSession对象:

  • 创建:调用request.getSession(true)方法
  • 销毁:
    1)默认情况下,30分钟服务器自动回收
    2)设置有效时长: session.setMaxActiveInterval(秒)
    3)手动销毁: session.invalidate()方法
    4)web.xml配置全局的过期时间
<session-config>    <session-timeout>分钟</session-timeout></session-config>   

例子:统计当前网站的访问数量

这里的统计不是实时统计,因为销毁需要一段时间,所以只是粗略统计

首先编写一个MySessionListener来监听在线人数,这里用到线程同步来避免统计错误,注意这里用上下文来保存count在线人数

import javax.servlet.ServletContext;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;public class MySessionListener implements HttpSessionListener {    // 用于存储当前网站的访客人数    private int count = 0;    // 用于监听HttpSession对象的创建    @Override    public void sessionCreated(HttpSessionEvent se) {        // System.out.println("一个session对象被创建了" + se.getSession());        ServletContext context = se.getSession().getServletContext();        // 使用代码同步避免多个用户同时访问的并发问题        synchronized (MySessionListener.class) {// 注意:锁对象必须是唯一的,类对象就是唯一的            count++;            // 把count通过context域对象共享到jsp页面            // 可以通过session对象获取到            context.setAttribute("onLine", count);        }    }    // 当用户对应的session对象销毁了,代表访客离线    @Override    public void sessionDestroyed(HttpSessionEvent se) {        // System.out.println("一个session对象被销毁了" + se.getSession());        ServletContext context = se.getSession().getServletContext();        synchronized (MySessionListener.class) {            count--;            context.setAttribute("onLine", count);        }    }}

在web.xml中配置监听器,这里省略
编写一个前端session.jsp来展现当前在线人数

<body>  <%  //修改session的过期时间    session.setMaxInactiveInterval(20);  %>    当前网站的在线访客人数为:${applicationScope.onLine }</body>

HttpSessionAttributeLisener

HttpSessionAttributeLisener用于监听HttpSession的属性操作

  • 增加属性: setAttribute(name,Object); 第一次就是增加属性
  • 修改属性: setAttribute(name,Object); 如果前面有增加了同名的属性,则修改。
  • 删除属性: removeAttribute(name);

例子:统计当前网站的登录用户信息

1)提供用户登录的功能,提供注销功能。
2)显示当前网站的所有登录用户信息
3)管理员可以踢除指定的登录用户。

原创粉丝点击