1

day25-Listener监听器 - 一刀一个小西瓜

 1 year ago
source link: https://www.cnblogs.com/liyuelian/p/16930560.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Listener监听器

1.Listener监听器介绍

  1. Listener监听器是JavaWeb三大组件之一。JavaWeb三大组件分别是:Servlet程序,Listener监听器,Filter过滤器。
  2. Listener是JavaEE的规范,即接口。
  3. 监听器的作用是,监听某种变化(一般就是对象的创建/销毁,属性变化),触发对象方法完成相应的任务。
  4. JavaWeb中的监听器共八个,目前最常用的是ServletContextListener,ServletContextAttributeListener,HttpSessionListener和ServletRequestListener

2.JavaWeb的监听器

2.1ServletContextListener监听器

  1. 作用:监听ServletContext创建或者销毁(当我们web应用启动时,Tomcat就会创建ServletContext对象),即生命周期监听
  2. 应用场景:
    • 加载初始化的配置文件;比如spring的配置文件
    • 任务调度(配合定时器Timer/TimerTask)
  3. 相关方法:
    • void contextInitialized(ServletContextEvent sce):创建ServletContext对象时触发
    • void contextDestroyed(ServletContextEven sce):销毁ServletContext对象时触发
  1. 首先创建一个项目,添加web支持,因为listener监听器是Servlet规范,要使用就要引入Servlet.jar包

    image-20221127165358783
  2. 创建一个普通类,如果该类实现了某个监听接口,那么此类就是一个监听器。该类可以监听的事件由该类实现的监听接口决定:

    package com.listener; import javax.servlet.ServletContext;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener; /** * 1.当一个类实现了 ServletContextListener 接口时 * 2.该类就是一个监听器 * 3.该类可以监听的事件由该类实现的监听接口决定 ,比如实现ServletContextListener接口, * 那么该类就可以监听ServletContext对象的创建和销毁,以此类推 * 4.下面的MyServletContextListener就是一个监听者 * 5.当web应用启动时,就会产生ServletContextEvent事件,会调用监听器的对应事件处理方法 * 如:contextInitialized(),同时会传递 事件对象 * 6.程序员可以通过 ServletContextEvent 事件对象,来获取需要的信息,然后再进行业务处理 * 7.Tomcat怎么知道这个监听器存在呢? 因为我们需要在web.xml文件中进行配置, * 一旦配置后,tomcat启动后就会反射实例化该监听器,放到容器里面去管理 */public class MyServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext(); System.out.println("MyServletContextListener监听到=" + servletContext + "被创建..."); //如果我们获取到ServletContext对象..可以进行业务处理 } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext(); System.out.println("MyServletContextListener监听到=" + servletContext + "被销毁..."); //比如可以对ServletContext 数据进行处理,或者日志的管理... System.out.println("进行处理工作..."); }}
  3. 配置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-class>com.listener.MyServletContextListener</listener-class> </listener></web-app>
  4. 配置Tomcat

  5. 点击启动tomcat时,我们可以看到监听器被触发了:

    image-20221127172929861
  6. 点击停止tomcat时,可以看到监听器再一次被触发:

    image-20221127172702514

2.2ServletContextAttributeListener监听器

  1. 作用:监听ServletContext属性的变化
  2. 相关方法:
    • void attributeAdded(ServletContextAttributeEvent event):添加属性时调用
    • void attributeReplaced(ServletContextAttributeEvent event):替换属性时调用
    • void attributeRemoved(ServletContextAttributeEvent event):移除属性时调用
  1. 创建监听器:MyServletContextAttributeListener
package com.listener; import javax.servlet.ServletContextAttributeEvent;import javax.servlet.ServletContextAttributeListener; public class MyServletContextAttributeListener implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("MyServletContextAttributeListener 监听到添加属性.." + servletContextAttributeEvent.getName() + "=" + servletContextAttributeEvent.getValue()); } @Override public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("MyServletContextAttributeListener 监听到删除属性.." + servletContextAttributeEvent.getName() + "=" + servletContextAttributeEvent.getValue()); } @Override public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("MyServletContextAttributeListener 监听到修改属性.." + servletContextAttributeEvent.getName() + "=" + servletContextAttributeEvent.getValue()); }}
  1. 创建servlet:HiServlet
package com.servlet; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException; public class HiServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //给ServletContext对象操作属性 ServletContext servletContext = getServletContext(); //添加属性 servletContext.setAttribute("name", "杰克"); //修改属性 servletContext.setAttribute("name", "托马斯"); //删除属性 servletContext.removeAttribute("name"); System.out.println("HiServlet 处理完毕..."); }}
  1. web.xml:配置监听器和servlet
<!--配置监听器--><listener> <listener-class>com.listener.MyServletContextAttributeListener</listener-class></listener><!--配置HiServlet--><servlet> <servlet-name>HiServlet</servlet-name> <servlet-class>com.HiServlet</servlet-class></servlet><servlet-mapping> <servlet-name>HiServlet</servlet-name> <url-pattern>/hiServlet</url-pattern></servlet-mapping>
  1. 重新发布tomcat,在浏览器中访问servlet,后台输出如下:

    image-20221127175211190

2.3HttpSessionListener监听器

  1. 作用:监听Session创建或销毁,即生命周期监听
  2. 相关方法:
    • void sessionCreated(HttpSessionEvent se):创建session时调用
    • void sessionDestroyed(HttpSessionEvent se):销毁session时调用
  3. 使用方法和前面一样,可以用于监听用户上线,离线
  1. 创建监听器:MyHttpSessionListener
package com.listener; import javax.servlet.http.HttpSession;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener; public class MyHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent httpSessionEvent) { HttpSession session = httpSessionEvent.getSession(); //当session被创建时,设置一个生命周期10s session.setMaxInactiveInterval(10); System.out.println("MyHttpSessionListener 监听到session创建= " + session.getId()); } @Override public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { HttpSession session = httpSessionEvent.getSession(); System.out.println("MyHttpSessionListener 监听到session销毁= " + session.getId()); }}
  1. 修改HiServlet代码:
package com.servlet; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException; public class HiServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session对象 request.getSession(); System.out.println("HiServlet 处理完毕..."); }}
  1. 配置监听器:
<listener> <listener-class>com.listener.MyHttpSessionListener</listener-class></listener>
  1. 现在我们重启Tomcat,可以看到还没有访问HiServlet,就已经创建了两个session。这是因为启动Tomcat时,会默认访问项目首页面,tomcat会自动创建两个session,这里忽略即可。

    image-20221127181720060
  2. 在浏览器访问HiServlet,可以看到后台首先创建了一个session,在设置的生命周期内不访问该session,显示该session被销毁。

    image-20221127182810302

HttpSessionListener监听器可以用于监听用户上线离线

注意:这里的session不是浏览器一关闭就销毁,session的销毁是服务器端去轮询决定的,因此如果想要用户浏览器一关闭就销毁session,可以通过前端在用户浏览器关闭之前,向服务器发送一个通知,服务器收到通知后销毁该session即可。

2.4HttpSessionAttributeListener监听器

  1. 作用:监听Session属性的变化
  2. 相关方法:
    • void attributeAdded(ServletRequestAttributeEvent event):添加属性时调用
    • void attributeReplaced(ServletRequestAttributeEvent event):替换属性时调用
    • void attributeRemoved(ServletRequestAttributeEvent event):移除属性时调用
  3. 使用少,使用方法和前面一样。
  1. 创建监听器:MyHttpSessionAttributeListener
package com.listener; import javax.servlet.http.HttpSessionAttributeListener;import javax.servlet.http.HttpSessionBindingEvent; public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener { @Override public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("MyHttpSessionAttributeListener 监听到 session添加属性= " + httpSessionBindingEvent.getName() + "=" + httpSessionBindingEvent.getValue()); } @Override public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("MyHttpSessionAttributeListener 监听到 session删除属性= " + httpSessionBindingEvent.getName() + "=" + httpSessionBindingEvent.getValue()); } @Override public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("MyHttpSessionAttributeListener 监听到 session修改属性= " + httpSessionBindingEvent.getName() + "=" + httpSessionBindingEvent.getValue()); }}
  1. 修改HiServlet
package com.servlet; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException; public class HiServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session对象 HttpSession session = request.getSession(); //添加属性 session.setAttribute("age", 888); //修改属性 session.setAttribute("age", 999); //删除属性 session.removeAttribute("age"); System.out.println("HiServlet 处理完毕..."); }}
  1. 配置监听器
<listener> <listener-class>com.listener.MyHttpSessionAttributeListener</listener-class></listener>
  1. redeployTomcat,在浏览器访问hiServlet,后台输出如下:

    image-20221127185403369

2.5ServletRequestListener监听器

  1. 作用:监听Request创建或者销毁,即Request对象的生命周期监听
  2. 相关方法:
    • void requestInitialized(ServletRequestEvent sre):创建request对象时触发
    • void requestDestroyed(ServletRequestEvent sre):销毁request对象时触发
  3. 可以用来监控某个IP访问我们网站的频率,做日志记录,或者访问资源的情况等。
  1. 创建监听器:MyServletRequestListener
package com.listener; import javax.servlet.ServletRequest;import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;import javax.servlet.http.HttpServletRequest; public class MyServletRequestListener implements ServletRequestListener { @Override public void requestInitialized(ServletRequestEvent servletRequestEvent) { System.out.println("MyServletRequestListener 监听到request对象被创建 "); ServletRequest servletRequest = servletRequestEvent.getServletRequest(); System.out.println("记录访问日志..."); System.out.println("访问IP= " + servletRequest.getRemoteAddr()); System.out.println("访问的资源= " + ((HttpServletRequest) servletRequest).getRequestURL()); } @Override public void requestDestroyed(ServletRequestEvent servletRequestEvent) { System.out.println("MyServletRequestListener 监听到request对象被销毁..."); }}
  1. hiServlet不做修改

  2. 配置监听器:

<listener> <listener-class>com.listener.MyServletRequestListener</listener-class></listener>
  1. redeployTomcat,在浏览器访问hiServlet,后台输出如下:

    (中间的session监听可忽略)

    image-20221127191733329
  2. 访问项目首页面,后台输出如下:

    image-20221127192003350

2.6ServletRequestAttributeListener监听器

  1. 作用:监听Request属性变化
  2. 相关方法
    • void attributeAdded(ServletRequestAttributeEvent srae):添加属性时调用
    • void attributeReplaced(ServletRequestAttributeEvent srae):替换属性时调用
    • void attributeRemoved(ServletRequestAttributeEvent srae):移除属性时调用
  3. 使用方法和前面类似

2.7HttpSessionBindingListener感知监听器

该监听器是用来绑定数据的。如果一个对象实现了HttpSessionBindingListener接口,当这个对象被绑定到Session中或者从session中被删除时,Servlet容器会通知这个对象,而这个对象在接收到通知后,可以做一些初始化或清除状态的操作。

2.8HttpSessionActivationListener感知监听器

HttpSessionActivationListener用于监控实现类本身,当实现类对象被添加到session属性中后,session对象序列化(钝化)前和反序列化(活化)后都会被执行

相应的方法:

  • sessionWillPassivate(HttpSessionEvent se): session钝化前执行(session从内存到硬盘)
  • sessionDidActivate(HttpSessionEvent se):session活化后执行(session从硬盘到内存)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK