hualinux servlet 2.18:监控器Listener

目录

一、知识点

1.1 简介

1.2 Servlet 监听器的分类

1.3 编写 Servlet 监听器

1.4 监听域对象的创建和销毁

1.5 ServletContextListener 接口(常用)

1.6 HttpSessionListener 接口

1.7 ServletRequestListener接口

1.8 小结

1.9 **ServletContextListener接口小结(常用)

1.10 ServletRequestListener接口和HttpSessionListener接口小结

二、例子

2.1 例1 简单的ServletContextListener

2.1.1相关文件

2.1.2相关代码

2.1.3 运行效果

2.2 例2 简单的ServletRequestListener和HttpSessionListener

2.2.1 相关文件入代码

2.2.2 运行效果

2.3 例3 简单的Listener来观察域对象生命周期

2.3.1 相关文件

2.3.2相关代码

2.3.3效果

2.4 其它例子


servlet监控器实际使用中相对比较少,可以了解一下

一、知识点

1.1 简介

  • 监听器:专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。
  • Servlet 监听器:Servlet 规范中定义的一种特殊类,它用于监听 web 应用程序中的 ServletContext, HttpSessionServletRequest 等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。

1.2 Servlet 监听器的分类

  • 按监听的事件类型 Servlet 监听器可分为如下三种类型:
    • 监听域对象自身的创建和销毁的事件监听器
    • 监听域对象中的属性的增加和删除的事件监听器
    • 监听绑定到 HttpSession 域中的某个对象的状态的事件监听器

1.3 编写 Servlet 监听器

  • Servlet 规范为每种事件监听器都定义了相应的接口,开发人员编写的事件监听器程序只需实现这些接口,web 服务器根据用户编写的事件监听器所实现的接口把它注册到相应的被监听对象上
  • 一些 Servlet 事件监听器需要在 web 应用程序的 web.xml 文件中进行注册,一个 web.xml 文件中可以注册多个 Servlet 事件监听器,web 服务器按照它们在 web.xml 文件中的注册顺序来加载和注册这些 Serlvet 事件监听器
  • Serlvet 事件监听器的注册和调用过程都是由 web 容器自动完成的,当发生被监听的对象被创建,修改或销毁事件时,web容器将调用与之相关的 Servlet 事件监听器对象的相关方法,开发人员在在这些方法中编写的事件处理代码即被执行
  • 由于一个 web 应用程序只会为每个事件监听器创建一个对象有可能出现多个线程同时调用同一个事件监听器对象的情况,所以,在编写事件监听器类时,应考虑多线程安全的问题

1.4 监听域对象的创建和销毁

  •    域对象创建和销毁的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象的创建和销毁事件的监听器。
  • 域对象的创建和销毁时机

1.5 ServletContextListener 接口(常用)

  • ServletContextListener 接口用于监听 ServletContext 对象的创建和销毁事件。
  • 当 ServletContext 对象被创建时,激发contextInitialized (ServletContextEvent sce)方法
  • 当 ServletContext 对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法

1.6 HttpSessionListener 接口

  • HttpSessionListener 接口用于监听HttpSession对象的创建和销毁
  • 创建一个Session时,激发sessionCreated (HttpSessionEvent se) 方法
  • 销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se) 方法。

1.7 ServletRequestListener接口

  • ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁
  • 创建一个ServletRequest 对象时,激发requestInitialized(ServletRequestEvent sre)方法
  • 销毁一个Session时,激发requestDestroyed(ServletRequestEvent sre)方法。

1.8 小结

1.监听器:专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。

2.监听器的分类:
1).监听域对象( HttpSssion, request, application )自身的创建和销毁的事件监听器
2) .监听域对象中的属性的增加和删除的事件监听器
3).监听绑定到HttpSession域中的某个对象的状态的事件监听器

3.如何编写监听器:
1).编写实现监听器接口的Java类

public class HelloServetContetListner implements ServletContextListener

2).对于第一一种和第二种监听器需要在web.xml文件中进行注册:

<listener>
<listener-class> com.atguigu.javaweb.test.HelloServletContextListner </listener-class>
</listener>

 4.监听域对象( HttpSession, request, application )自身的创建和销毁的事件监听器
1). ServletContextListener :最常用的Listener,可以在当前WEB应用被加载时对当前WEB应用的相关资源进行初始化操作:创建数据库连接池,创建Spring的I0C容器,读取当前WEB应用的切始化参数..
2). ServletRequestlistener,
3). HttpSessionListener

在每个监控器中都有两个方法:

    >在域对象创建后立即被调用的方法:
    >在域对象销毁前被调用的方法:

方法的参数:以ServletContextEvent为例,该对象可以返回ServletContext对象。

5.监听ServletContext, HttpSession, ServletRequest中添加属性,替换属性移除属性的事件监听器,(了解即可)
1).以ServletRequestAttributeListener为例:

//添加属性时被调用
public void attributeAdded(ServletRequestAttributeEvent srae) {
System.out.printn("向request中添加了一个属性.");
//移除属性时被调用
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.printn("从request中移除了-个属.."):
/替换属性时被调用.
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
System.out.printin(request中属性替换..);

2).这三个ServletContextAttributeListener,
ServletRequestAtributeListener, HttpSessionAttributeListener监听器较少被使用.
3). API:
ServletRequestAttributeEvent:
    > getName0:获取属性的名字
    > getValue0: 获取属性的值.
 

6.监听绑定到HttpSession域中的某个对象的状态的事件监听器
1 ). HttpSessionBindingListener (了解即可) :
①.监听实现了该接口的Java类的对象被绑定到session或从session中解除绑定的事件.
//当前对象被绑定到session时调用该方法
public void valueBound(HttpSessionBindingEvent event)
//当前对象从session中解除绑定调用该方法
public void valueUnbound(HttpSessionBindingEvent event)
②.注意:该监听器不需要在web.xml文件中进行配置.
③. HttpSessionBindingEvent:
getName0
getValue(
getSession0

2). HttpSessionActivationListener (该监听器较少被使用) :
①.监听实现了该接口和Serializable接口(若不实现该接口,则只能写到磁盘上,但不能读取出来)的Java类的对象随session钝化和活化事件
    >活化:从磁盘中读取session对象
    >钝化:向磁盘中写入session对象
    > session对象存储在tomcat服务器的work\CatalinaVocalhost\contextPath目录下. SESSION.SER
②.该监听器不需要在web.xml文件中进行配置.

③.//在活化之后被调用.
public void sessionDidAtiate(HttsessionEvent se)
//在钝化之前被调用
public void ssiotWlassiatHttpSessionEvent se)
HttpSessionEvent: getSession0

1.9 **ServletContextListener接口小结(常用)

ServletContextListener:
1). what: 监听ServletContext对象被创建或销毁的Servlet监听器

2). how:
    >创建一个实现了ServletContexltListener的类,并且实现其中的两个方法
    public class HelloServletContextListner implements ServletContextL istener
    >在web.xml文件中配置Listener

<listener>
<listener- class>com.hualinux.javaweb.test.HelloServletContextListner</1istener-class>
</listener>

3). why: ServletContextListener 是最常用的Listener,可以在当前WEB应用被加载时对当前WEB应用的相关资源进行初始化操作:
创建数据库连接池,创建Spring的IOC容器,读取当前WEB应用的初始化参数...

4). API:
// SerlvetContext 对象被创建(即,当前WEB应用被加载时)的时候,Servlet 容器调用该方法。
public void contextInitialized(ServletContextEvent sce)
// SerlvetContext 对象被销毁之前(即,当前WEB应用被卸载时)的时候,Servlet 容器调用该方法。
public void contextDestroyed(ServletContextEvent sce)

ServletContextEvent中的: getServletContext() 获取ServletContext

此接口只有2个方法:

1.10 ServletRequestListener接口和HttpSessionListener接口小结

ServletRequestListener & HttpSessionListener
1).和ServletContextListener类似。

2).利用ServletRequestListener. HttpSessionListener 以及ServletContextListener可以把request, session
及application的生命周期进一步的做一 了解。
    >request: 是一一个请求, 当一个响应近回时,即被销毁。当发送一个请求时被创建。注意,请求转发的过程是一个request对象.
重定向是两个请求
    >session: 当第-次访问WEB应用的一个JSP或Servlet 时,且该JSP或Servlet 中还需要创建session 对象。此时服务器会
创建-一个session对象。

 session销毁: session 过期,直按调用session的invalidate方法,当前web应用被卸载(session可以被持久化)
申关闭浏览器,并不意味着session被销毁,还可以通过sessionid找到服务器中的session 对象.

JSESSIONID=F4119DE0FC93ED38E8EC83B24CFA3B81
http://1ocalhost :8989/day_ _40/ sess ion. jsp;jsessionid=F 4119DE0FC93ED38E8EC83B24CFA3B81

 >application: 贯穿于当前的WEB应用的生命周期。当前WEB应用被加载时创建application对象,当前WEB应用被卸载时
销毁application对象.|

各自也只有2个方法:

Interface ServletRequestListener所有方法

Interface HttpSessionListener所有的方法 

二、例子

监听器中最重要的是ServletContextListener、ServletRequestListener和HttpSessionListener,其它的都不常用,故主要是以它们为例。

2.1 例1 简单的ServletContextListener

         ServletContextListener接口中的方法输出一些内容

2.1.1相关文件

2.1.2相关代码

src-->com.hualinux.listener1-->HelloServletContextListener.java

package com.hualinux.listener1;

import javax.servlet.*;

public class HelloServletContextListener  implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 对象被创建");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 对象被销毁");
    }
}

web-->WEB-INF-->web.xml

为了方便,我把前章过滤器的配置注解掉。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- listener  -->
    <listener>      <listener-class>com.hualinux.listener1.HelloServletContextListener</listener-class>
    </listener>
</web-app>

web-->index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>
</head>
<body>
<h3>index html page</h3>>
</body>
</html>

2.1.3 运行效果

主要是看tomcat的输出信息,如下图:

上图中,只出现对象被创建,如要输出把网页关闭也是不行的,可以停止tomcat试下,如下图:

上面停止了tomcat,出现了“ServletContext 对象被销毁”。

 

2.2 例2 简单的ServletRequestListener和HttpSessionListener

我们可以在上面2.1的例子基础上直接再继承ServletRequestListener和HttpSessionListener接口,它们也是2个方法

2.2.1 相关文件入代码

src-->com.hualinux.listener1-->HelloServletContextListener.java代码修改如下:

package com.hualinux.listener1;

import javax.servlet.*;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class HelloServletContextListener  implements ServletContextListener, ServletRequestListener,HttpSessionListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 对象被创建");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 对象被销毁");
    }

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("ServletRequest 对象被销毁");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("ServletRequest 对象被创建");
    }

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("HttpSession 对象被创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("HttpSession 对象被销毁");
    }
}

2.2.2 运行效果

         主要也是看IDE最下方的tomcat的输出信息

现在关闭网页手工输入:http://localhost:8080/index.html,多输出了:

ServletRequest 对象被创建
ServletRequest 对象被销毁
我们再打开一个陌生动态的网页,如之前的hello.jsp,
http://localhost:8080/hello.jsp,发现多出了三行
ServletRequest 对象被创建
HttpSession 对象被创建
ServletRequest 对象被销毁

关闭刚才打开的新页面,发现没有变化,说明只关闭页面,session不会被销毁

tomcat停止试下,发现只有“ServletContext 对象被销毁”

说明session没有被销毁,需要手工操作,可以使用“session.invalidate();”方法

hello.jsp修改为

<%
    session.invalidate();
%>

再运行访问此页面试下,多出了:

ServletRequest 对象被创建
HttpSession 对象被创建
HttpSession 对象被销毁
ServletRequest 对象被销毁

2.3 例3 简单的Listener来观察域对象生命周期

JavaWeb 应用中,被监听的对象主要是:ServletContextHttpSessionServletRequest

对应的监听器为ServletContextListenerServletRequestListenerHttpSessionListener

2.3.1 相关文件

以上面“10.2.22”为基础,在web下新建立一个index.jsp

修改一下test.jspcom.hualinux.listener1-->HelloServletContextListener.java文件

2.3.2相关代码

web-->index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    <h3>index page</h3>
    <a href="test.jsp">test page</a>
    <%
        request.setAttribute("requestKey","requestValve");
    %>

</body>
</html>

web-->test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
  <head>
    <title>test</title>
    <meta charset="UTF-8">
  </head>
  <body>
    <h3>Test Page</h3>
   <%= request.getAttribute("requestKey") %>
  </body>
</html>

src-->com.hualinux.listener1-->HelloServletContextListener.java

package com.hualinux.listener1;

import javax.servlet.*;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class HelloServletContextListener  implements ServletContextListener, ServletRequestListener,HttpSessionListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 对象被创建"+servletContextEvent.getServletContext());
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 对象被销毁"+servletContextEvent.getServletContext());
    }

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("ServletRequest 对象被销毁");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("ServletRequest 对象被创建");
    }

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("HttpSession 对象被创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("HttpSession 对象被销毁");
    }
}

2.3.3效果

idea运行会自动转到主页

从上面发现“requestKey”是空的,没有把index.jsp的“requestKey”传过来。

查看IDE当访问index.jsp页面的时候发现,idetomcat信息如下:

ServletRequest 对象被创建

ServletRequest 对象被销毁

请求马上被注销了,所以获取不到requestKey的值。

解决方法:

通过请求转发把index.jsp页面的属性转发过来,所以在index.jsp添加一条

<jsp:forward page="test.jsp"/>

index.jsp整体代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    <h3>index page</h3>
    <a href="test.jsp">test page</a>
    <%
        request.setAttribute("requestKey","requestValve");
    %>
    <jsp:forward page="test.jsp"/>
</body>
</html>

重启tomcat,会

如果上面不用jsp:forward,也可以单独写一个servlet

新建立一个类src-->com.hualinux.listener1-->TestServlet.java

package com.hualinux.listener1;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("requestKey","requestvalue2");
        //如果使用下面那个也会结果为空
        //resp.sendRedirect("test.jsp");
        req.getRequestDispatcher("/test.jsp").forward(req,resp);
    }
}

index.jsp做如下修改:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    <h3>index page</h3>
    <a href="test.jsp">test page</a>

<%--
    <%
        request.setAttribute("requestKey","requestValve");
    %>
    <jsp:forward page="test.jsp"/>

--%>
    <br><br>
    <a href="/testservlet">testServlet</a>

</body>
</html>

2.4 其它例子

主要还是注意一下session,这里就不说了

>session: 当第-次访间WEB应用的一个JSP或Servlet 时,且诙JSP或Servlet 中还需要创建session 对象。此时服务器会
创建-一个session 对象。
    session销毁: session 过期,直接调用session的invalidate方法,当前web应用被卸载(session可以被持久化) .
    *关闭浏览器,并不意味着session 被销毁,还可以通过sessionid 找到服务器中的session 对象.

还有一个application,这个不太常用
>application: 贯穿于当前的WEB应用的生命周期。当前WEB应用被加载时创建application对象,当前WEB应用被卸载时销毁application对象。|

猜你喜欢

转载自blog.csdn.net/hualinux/article/details/106838967