12. JSP - 监听器 - JavaWEB

Javaweb中的监听器Listener

servlet中的监听器

servlet中的监听器是用于监听web常见对象HttpServletRequest,HttpSession,ServletContext。主要有下面三个作用:
1.监听web对象创建与销毁。
2.监听web对象的属性变化,添加、删除、修改
3.监听session绑定javaBean操作活化(从硬盘读取到内存)与钝化(从内存持久化到硬盘)操作
当监听器发现被监听的对象发生变化时,可以做一些操作

在servlet中一共有8个监听器,按照监听器的作用分类如下:

    • 监听web对象创建与销毁的监听器
      • ServletContextListener
      • HttpSessionListener
      • ServletRequestListener
    • 监听web对象属性变化的监听器
      • ServletContextAttributeListener
      • HttpSessionAttributeListener
      • ServletRequestAttributeListener
    • 监听session绑定javaBean操作的监听器
      • HttpSessionBindingListener
      • HttpSessionActivationListener

监听器的创建和使用

javaweb创建监听器的步骤:

  1. 创建一个类,实现指定的监听器接口
  2. 重写接口中的方法
  3. 在web.xml文件中配置监听器

监听对象的创建和销毁
下面演示监听HttpServletRequest对象的销毁和创建

1.创建一个类实现ServletRequestListener接口:

ServletRequestListener接口 里面有两个 默认方法(Default),我们直接重写即可:

package jtq;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class listener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("Request 被我销毁了");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("Request 生成了");
    }

}

在XML中配置监听器:

<listener>
<listener-class>jtq.listener</listener-class>
</listener>

记住这格式!

 

然后你就在你控制台看到你的 request 创建又销毁 来来回回的了...

 

同理,在监听HttpSesssion对象的创建与销毁时,需要创建一个类实现HttpSessionListener接口并重写里面的方法。【其他的都一样的啊! 直接实现重写然后配置!】即:

在监听ServletContext对象的创建与销毁时,创建一个类实现ServletContextListener接口并重写里面的方法即可。

什么情况下会销毁session:

  • 默认超时 30分钟
  • 关闭服务器
  • invalidate()方法
  • setMaxInactiveInterval(int interval) 可以设置超时时间

  

这个对象的监听就是这样的啊  具体其他自己去实现接口 重写 配置xml 即可。。。

这里他会检测全局【JSP 、 Servlet 都是....】\

自己试试!!!


监听属性的变化

以监听在HttpServletRequest对象中添加、修改、删除属性为例:

其他的 session 啊 什么什么的 自己去用这种方式去试即可!  一定要动手:

首先 实现 HttpServletRequest 接口 然后我们重写他的方法【注释有解析】:

package Attribute;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;

public class Listeners_Attribute  implements ServletRequestAttributeListener {
    
  



    @Override
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        System.out.println("request 发生了变化  添加了" + srae.getName() + ", 他的值是:" + srae.getValue()  );
    }



    @Override
    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        //删除reqeust属性时 触发
        System.out.println("request 发生了变化  删除了" + srae.getName() + ", 他的值是:" + srae.getValue()  );
    }



    @Override
    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        //修改reqeust属性时 触发
        System.out.println("request 发生了变化  修改了" + srae.getName() + ", 他的值是:" + srae.getValue()  );
    
    }

    
}

 

然后JSP页面写:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <% 
        request.setAttribute("name", "bihu");
        request.setAttribute("name","bihu-2");
        request.removeAttribute("name");
    %>
</body>
</html>

然后 web.XML 里面写:

  <listener>
  <listener-class>Attribute.Listeners_Attribute</listener-class>
  </listener>

 

然后你可以看到:

request 发生了变化  修改了org.apache.catalina.ASYNC_SUPPORTED, 他的值是:true
request 发生了变化  添加了name, 他的值是:bihu
request 发生了变化  修改了name, 他的值是:bihu
request 发生了变化  删除了name, 他的值是:bihu-2

//我也不知道为什么第一个会冒出来,但我知道他是监听修改的出来的

其他的自己按照这个套路去试试!!! 这里不多说了!

这里他会检测全局的request【JSP 、 Servlet 都是....】的啊 就是 反正有 request 被改变 那么我就触发【这不就是 观察者模式吗 啊哈哈哈哈】


 

 监听session绑定javabean

HttpSessionBindingListener监听器可以使javaBean对象在被绑定到会话或从会话中取消对它的绑定时得到通知

该监听器是由实体类来实现,需要注意的是该监听器的实现类不需要在web.xml文件中进行配置(也可以配置 一般不用都可以

 

你可以在Eclipse 中 new  然后直接一个 监听器 然后实现 HttpSessionBindingListener 接口,且重写他的方法 然后添加你的set 和 get :

package Attribute;

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

/**
 * 自动监听器
 *
 */
public class Student implements HttpSessionBindingListener {

    private String name;
    private int age;
  
public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public void valueBound(HttpSessionBindingEvent event) { //绑定时 触发 System.out.println( event.getName() + "被Session绑定了(添加了)" ); } @Override public void valueUnbound(HttpSessionBindingEvent event) { //解绑时 触发 System.out.println( event.getName() + "被Session解绑了(删除了)" ); } }

 

然后新建一个 JSP 你就可以监听到 他是否被Session 绑定 和 解绑了:

<%@page import="Attribute.Student"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <% 
    //这个为 测试类 JSP 当访问时 就会触发Student被绑定的事件
    Student stu = new Student();
    session.setAttribute("studnet", stu);
    session.removeAttribute("studnet");
    %>
    
    <%-- 
        运行后你就会看到:        
        
        studnet被Session绑定了(添加了)
        studnet被Session解绑了(删除了)
     
     --%>
</body>
</html>

 


 

 

 

 

监听在 Session 中存放的指定类型对象的钝化与活化(了解)
HttpSessionActivationListener该监听器用于监听在 Session 中存放的指定类型对象的钝化与活化
钝化是指将内存中的数据写入到硬盘中,而活化是指将硬盘中的数据恢复到内存。当用
户正在访问的应用或该应用所在的服务器由于种种原因被停掉,然后在短时间内又重启,此时用户在访问时 Session 中的数据是不能丢掉的在应用关闭之前,需要将数据持久化到硬盘中
在重启后应可以立即重新恢复 Session 中的数据。这就称为 Session 的钝化与活化
那么 Session 中的哪些数据能够钝化呢?只有存放在 JVM 堆内存中的实现了 Serializable
类的对象能够被钝化。也就是说,对于字符串常量、基本数据类型常量等存放在 JVM 方法
区中常量池中的常量,是无法被钝化的
对于监听 Session 中对象数据的钝化与活化,需要注意以下几点:

    • 实体类除了要实现 HttpSessionActivationListener 接口外,还需要实现 Serializable 接口
    • 钝化指的是 Session 中对象数据的钝化,并非是 Session 的钝化。所以 Session 中有几个可以钝化的对象,就会发生几次钝化。
    • HttpSessionActivationListener 监听器是不需要在 web.xml 中注册的

 

1.创建Person类实现HttpSessionActivationListener和Serializable接口:

package Attribute;

import java.io.Serializable;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;

public class Person implements HttpSessionActivationListener,Serializable{

private static final long serialVersionUID = -3274136342116934283L; //一定要随机UID 不然看你无法钝化 为什么? 就要看你IO学的怎么样了

private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public void sessionDidActivate(HttpSessionEvent se) { System.out.println("活化" + se.getSession().getId()); } @Override public void sessionWillPassivate(HttpSessionEvent se) { System.out.println("钝化" + se.getSession().getId()); } }

2.在项目中的META-INF目录下创建一个content.xml的文件,在里面写上下面内容:

<?xml version="1.0" encoding="UTF-8"?>

<!-- 在项目中的META-INF目录下创建一个content.xml的文件,在里面写上下面内容:
    一定要是 content 这个文件名 不然没用        
 -->

<Context>
    <!-- ClassName 是 序列化相关的东西     maxIdleSwap 是多少秒后去序列化     -->
    <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
    <!-- ClassName 是 序列化相关的东西     directory 存储的位置     -->
    <Store className="org.apache.catalina.session.FileStore" directory="bihu"/>
    </Manager>
</Context>

一定别写错啊 这玩意

 

3.3.在jsp中编写下面内容 把 Person 实例化后 将他 存到Session 中:

<%@page import="Attribute.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <% 
    Person p = new Person();
    session.setAttribute("Person", p);
    //当服务器启动时 自动活化 Person  当服务器关闭时 就钝化Person
    %>
</body>
</html>

 

 

通过上面的设置,可以将session钝化和活化。
启动tomcat访问jsp文件,之后正常关闭tomcat后可以看见控制台输出”钝化”。再次启动tomcat,可以看到控制台输出”活化”。

 你会发现 钝化 和 活化的 ID 是一样的 那就没错了  你可以去工作目录去找你钝化后的文件 ser 结尾的  ,但活化后会消失。

 

 

自己试一试     主要还是一点 多实践起来

 

posted @ 2021-06-06 15:34  咸瑜  阅读(243)  评论(0编辑  收藏  举报