监听器

2020-08-26  本文已影响0人  码而优则仕

监听器

为了能够在 Servlet 应用程序中进行事件驱动编程,Servlet API 提供了一整套事件类和监听器接口。所有事件类均源自java.util.Event,并且监听器在以下三个不同级别中均可用:ServletContextHttpSession,ServletRequest.

监听器接口和注册

ServletContextListener

ServletContextAttributeListener

HttpSessionListener

HttpSessionActivationListener

HttpSessionAttributeListener

HttpSessionBindingListener

ServletRequestListener

ServletRequestAttributeListener

AsyncListener。

注册监听器有两种方式:注解(@WebListener)/在部署描述符(web.xml)中配置

<listener>
  <listener-class>
  </listener-class>
</listener>

ServletContext 监听器

在ServletContext 级别上有两个监听器接口:ServletContextListener,ServletContextAttributeListener

ServletContextListener:

ServletContextListener会对 ServletContext 的初始化和解构做出响应。ServletContext被初始化的时候,Servlet容器会在所有已注册的ServletContextListener中调用 contextInitialized 方法,方法签名如下:

实例如下:

JSTL 依赖引入:

<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
package cn.com.yuns.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.util.HashMap;
import java.util.Map;

/**
 * 以注解的方式申明监听器
 *
 * @author wsq
 * @version AppListener.java  2020/7/30  上午8:32 上午
 */
@WebListener
public class AppListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        Map<String, String> countries = new HashMap<>();
        countries.put("ca", "China");
        countries.put("jp", "Japan");
        countries.put("am", "American");
        servletContext.setAttribute("countries", countries);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }

}
<%--
  Created by IntelliJ IDEA.
  User: wsq
  Date: 2020/7/30
  Time: 8:36 上午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Country List</title>
</head>
<body>
we operate in these countries:
<ul>
    <c:forEach items="${countries}" var="country">
        <li>
                ${country.value}
        </li>
    </c:forEach>
</ul>
</body>

</html>

ServletContextAttributeListener:

每当ServletContext 中添加,删除或替换了某个属性时,所有注册的实现了ServletContextAttributeListener的监听器都会收到通知:

下面是这个监听器接口定义的三个方法:

Session监听器

与HttpSession 有关的监听器接口有四个:HttpSessionListener,HttpSessionActivationListener,HttpSessionAttributeListener,HttpSessionBindingListener。

HttpSessionListener:

当有HttpSession 被创建或者销毁的时候,Servlet 容器就会调用所有已经注册的HttpSessionListener。

HttpSessionListener:定义了两个方法:

实例如下:

package cn.com.yuns.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author wsq
 * @version SessionListener.java  2020/7/30  上午8:59 上午
 */
@WebListener
public class SessionListener implements HttpSessionListener, ServletContextListener {


    /**
     * ServletContext 初始化的时候调用该方法,初始化用户人数为 0
     *
     * @param sce
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("userCounter", new AtomicInteger());
    }

    /**
     * Session 会话被创建的时候,表示有新的用户访问网站,故而使用人数加一
     *
     * @param se
     */
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        ServletContext servletContext = session.getServletContext();
        AtomicInteger userCounter = (AtomicInteger) servletContext.getAttribute("userCounter");
        int userCount = userCounter.incrementAndGet();
        System.out.println("new user welcome current user is :" + userCount);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        ServletContext servletContext = session.getServletContext();
        AtomicInteger userCounter = (AtomicInteger) servletContext.getAttribute("userCounter");
        int userCount = userCounter.decrementAndGet();
        System.out.println("has user leave current user is :" + userCount);
    }
}

HttpSessionAttributeListener

当HttpSession中有添加,删除或者替换属性的时候就会被调用

HttpSessionActivationListener:

在分布式环境中,多个Servlet 容器会配置成可伸缩的,为了节约内存,Servlet容器可以对session属性进行迁移或者序列化。一般来说,当内存比较低时,相对较少访问的对象可以序列化到备用存储设备中,这样,Servlet容器就能够注意到哪些Session属性的类实现了HttpSessionActivationListener接口。

这个接口中定义了两个方法:

HttpSessionBindingListener

当 HttpSessionBindingListener绑定到HttpSession,或者取消绑定时,都会收到通知。如果一个类香知道什么时候绑定或者取消绑定到HttpSession上,那么这个类要实现HttpSessionBindingListener接口,然后将它的实例保存为session 属性,它就可以自动更新。再比如,一旦HttpSessionBindingListener与HttpSession取消绑定,它的实现类就可以释放占用的资源。

实例如下:

package cn.com.yuns.listener;

import lombok.Data;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

/**
 * @author wsq
 * @version Product.java  2020/7/30  上午11:13 上午
 */
@WebListener
@Data
public class Product implements HttpSessionBindingListener {

    private String id;

    private String name;

    private double price;

    /**
     * 绑定时调用该方法
     *
     * @param event
     */
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        String attributeName = event.getName();
        System.out.println(attributeName + " valueBound");
    }

    /**
     * 解绑时调用该方法
     *
     * @param event
     */
    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        String attributeName = event.getName();
        System.out.println(attributeName + " valueUnbound");
    }
}

ServletRequest监听器:

在ServletRequest 级别上有三个监听器接口:ServletRequestListener,ServletRequestAttributeListener,和AsyncListener。

ServletRequestListener对ServletRequest的创建和销毁做出响应。在Servlet容器中是通过池来重用ServletRequest的,创建ServletRequest花费的时间相当于从池中获取它的时间,ServletRequest销毁时间则相当于它返回到池中的时间。

ServletRequestListener 接口定义了如下两个方法:

ServletRequestAttributeListener

当在ServletRequest中添加,删除或者替换某个属性的时候,会调用 ServletRequestAttributeListener ;该接口定义了三个方法:

上一篇 下一篇

猜你喜欢

热点阅读