亲宝软件园·资讯

展开

Java Listener监听器使用规范详细介绍

@每天都要敲代码 人气:0

1、什么是监听器以及监听器作用

①监听器是Servlet规范中的一员。就像Filter一样。Filter也是Servlet规范中的一员。

②在Servlet中,所有的监听器接口都是以“Listener”结尾。

③监听器实际上是Servlet规范留给我们javaweb程序员的特殊时机。

④特殊的时刻如果想执行这段代码,你需要想到使用对应的监听器。

2、Servlet规范中提供了哪些监听器

javax.servlet包下:

①ServletContextListener

②ServletContextAttributeListener

③ServletRequestListener

④ServletRequestAttributeListener

jakarta.servlet.http包下:

①HttpSessionListener

②HttpSessionAttributeListener

③HttpSessionBindingListener

④HttpSessionIdListener

⑤HttpSessionActivationListener

3、实现一个监听器的步骤

这里主要先讲解熟悉的关于三个域对象的监听器:

ServletContext、ServletRequest、HttpSession

(1)以ServletContextListener为例

①第一步:编写一个类实现ServletContextListener接口。并且实现里面的方法。

监听器中的方法不需要程序员手动调用。是发生某个特殊事件之后被服务器调用。

// ServletContext对象被创建的时候调用。
void contextInitialized(ServletContextEvent event)
// ServletContext对象被销毁的时候调用
void contextDestroyed(ServletContextEvent event)

②第二步:在web.xml文件中对ServletContextListener进行配置,如下:

当然,第二步也可以不使用配置文件,也可以用注解,例如:@WebListener 即可。

   <listener>
        <listener-class>com.bjpowernode.javaweb.servlet.MyServletContextListener</listener-class>
    </listener>

注意:所有监听器中的方法都是不需要javaweb程序员调用的,由服务器来负责调用。

什么时候被调用呢?当某个特殊的事件发生(特殊的事件发生其实就是某个时机到了)之后,被web服务器自动调用。

③服务器启动时,ServletContext对象创建,contextInitialized方法执行

服务器关闭时,ServletContext对象销毁,contextDestroyed方法执行

package com.bjpowernode.javaweb.servlet;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
 * @Package:com.bjpowernode.javaweb.servlet
 * @Project:JavaWeb
 * @name:MyServletContextListener
 */
// ServletContextListener监听器主要监听的是:ServletContext对象的状态。
public class MyServletContextListener implements ServletContextListener { // 服务器启动时间点
    /**
     * 监听器中的方法不需要程序员手动调用。是发生某个特殊事件之后被服务器调用。
     * @param sce
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) { // 服务器关闭时间点
        // 现在这个特殊的时刻写代码,你写就是了。它会被服务器自动调用。
        // 这个方法是在ServletContext对象被创建的时候调用。
        System.out.println("ServletContext对象创建了。");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 现在这个特殊的时刻写代码,你写就是了。它会被服务器自动调用。
        // 这个方法是在ServletContext对象被销毁的时候调用。
        System.out.println("ServletContext对象被销毁了。");
    }
}

(2)以ServletRequestListener为例

④ServletRequest对象是一次请求创建一个request对象,所以服务器启动后:

只要发送一次请求就会调用requestInitialized方法,请求结束立刻会调用requestDestroyed

注:我们直接访问http://localhost:8080/servlet15/会报404错误,因为默认会访问index.html,但是我们并没有写;就算如此也会发送出请求,执行这个监听器。

package com.bjpowernode.javaweb.servlet;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
/**
 * @Package:com.bjpowernode.javaweb.servlet
 * @Project:JavaWeb
 * @name:MyServletRequestListener
 */
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
    // request对象销毁时间点
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("request对象销毁了");
    }
    // request对象创建时间点
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("request对象初始化了");
    }
}

(3)以HttpSessionListener为例

⑤我们都知道在访问jsp时,默认会创建session对象(九大内置对象);先编写一个my.jsp;在访问my.jsp时,会创建session对象,调用 sessionCreated方法;

当退出系统时,我们编写销毁session对象的方法,会调用sessionDestroyed方法。

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
my jsp page
<a href="${pageContext.request.contextPath}/exit" rel="external nofollow" >退出系统</a>
</body>
</html>

根据/exit请求,编写销毁session对象的类

package com.bjpowernode.javaweb;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
 * @Package:com.bjpowernode.javaweb
 * @Project:JavaWeb
 * @name:ExitServlet
 */
@WebServlet("/exit")
public class ExitServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取session对象
        HttpSession session = request.getSession(false);
        if (session != null) {
            // 销毁session
            session.invalidate();
        }
    }
}

(4)AttributeListener的使用

①我们知道对于域对象都有setAttribute、getAttribute、removeAttribute方法,分别可以向域中存数据、取数据、清除数据;所以对于AttributeListener肯定是和这些处理域中数据有关。

②实际上对于ServletContextAttributeListener、ServletRequestAttributeListener 、HttpSessionAttributeListener这三个对象都有attributeAdded、attributeRemoved、attributeReplaced方法;表示:向域当中存储数据的时候调用、向域当中删除数据的时候调用、向域当中替换数据的时候调用。

③这里以HttpSessionAttributeListener对象为例:

编写HttpSessionAttributeListener监听器

package com.bjpowernode.javaweb.servlet;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
/**
 * @Package:com.bjpowernode.javaweb.servlet
 * @Project:JavaWeb
 * @name:MyHttpSessionAttributeListener
 */
@WebListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
    // 向session域当中存储数据的时候,以下方法被WEB服务器调用。
    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        System.out.println("session data add");
    }
    // 将session域当中存储的数据删除的时候,以下方法被WEB服务器调用。
    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        System.out.println("session data remove");
    }
    // session域当中的某个数据被替换的时候,以下方法被WEB服务器调用。
    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
        System.out.println("session data replace");
    }
}

编写Servlet类用来处理域中的数据

当发送http://localhost:8080/servlet15/session/attribute/test就能触发上面的监听器;

注意:调用getAttribute方法不会触发,只有setAttribute方法和removeAttribute方法才会触发

package com.bjpowernode.javaweb;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
 * @Package:com.bjpowernode.javaweb
 * @Project:JavaWeb
 * @name:HttpSessionAttributeServlet
 */
@WebServlet("/session/attribute/test")
public class HttpSessionAttributeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取session对象
        HttpSession session = request.getSession();
        // 向session域中存储数据
        session.setAttribute("user", "zhangsan");
        // 替换,覆盖上面的数据
        session.setAttribute("user", "lisi");
        // 删除
        session.removeAttribute("user");
    }
}

4、HttpSessionBindingListener

(1)前面我们已经讲解了关于域对象的监听器,九个监听器中就已经学习了6个;接下来就先分析一下HttpSessionBindingListener;顾名思义就是关于数据绑定的!

(2)下面就通过一个例子来学习一下HttpSessionBindingListener监听器:

创建一个user1类实现监听器(不需要@WebListener注解),并重写方法

创建一个user2类不实现监听器

对比当数据放入放入域当中,两者会有什么区别:

①普通的user1类实现监听器,并重写监听器中两个方法

package com.bjpowernode.javaweb.bean;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
/**
 * 普通的java类。但是它实现了:HttpSessionBindingListener
 */
public class User1 implements HttpSessionBindingListener {
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("绑定数据");
    }
    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        System.out.println("解绑数据");
    }
    private String usercode;
    private String username;
    private String password;
    public User1(String usercode, String username, String password) {
        this.usercode = usercode;
        this.username = username;
        this.password = password;
    }
    public User1() {
    }
    public String getUsercode() {
        return usercode;
    }
    public void setUsercode(String usercode) {
        this.usercode = usercode;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

②普通的user2类不实现监听器

package com.bjpowernode.javaweb.bean;
/**
 * 普通的java类。
 */
public class User2 {
    private String usercode;
    private String username;
    private String password;
    public User2() {
    }
    public User2(String usercode, String username, String password) {
        this.usercode = usercode;
        this.username = username;
        this.password = password;
    }
    public String getUsercode() {
        return usercode;
    }
    public void setUsercode(String usercode) {
        this.usercode = usercode;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

③编写一个servlet类,把这两种数据都存进去

发现实现监听器的user1类会触发绑定事件!

package com.bjpowernode.javaweb.servlet;
import com.bjpowernode.javaweb.bean.User1;
import com.bjpowernode.javaweb.bean.User2;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/session/bind")
public class HttpSessionBindingListenerServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取session对象
        HttpSession session = request.getSession();
        // 准备两个对象:User1 User2
        User1 user1 = new User1("111", "zhangsan", "123");
        User2 user2 = new User2("111", "zhangsan", "123");
        // 将user1存储到session域
        session.setAttribute("user1", user1);
        // 将user2存储到session域
        session.setAttribute("user2", user2);
    }
}

(3)区分:HttpSessionAttributeListener 和HttpSessionBindingListener

加载全部内容

相关教程
猜你喜欢
用户评论