Filter+Listener核心技术

一、Filter过滤器(重点)

1、基本概念

  • Filter本意为”过滤“的含义,是JavaWeb的三大组件之一,三大组件为:Servlet、Filter、Listener。
  • 过滤器是向 Web 应用程序的请求和响应处理添加功能的 Web 服务组件。
  • 过滤器相当于浏览器与Web资源之间的一道过滤网,在访问资源之前通过一系列的过滤器对请求进行修改、判断以及拦截等,也可以对响应进行修改、判断以及拦截等。

2、工作方式

image-20210818210801188

3、使用方式

  • 自定义类实现Filter接口并重写doFilter方法。
public class LoginFilter implements Filter {
  
    public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException,ServletException {
        //TODO 处理逻辑,必须调用下面的方法
        chain.doFilter(request,response);
    }
}
  • 在web.xml文件中配置过滤器。
<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.lagou.LoginFilter</filter-class>
</filter>
  
<filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

4、Filter接口

1.基本概念

  • javax.servlet.Filter接口主要用于描述过滤器对象,可以对资源的请求和资源的响应操作进行筛选操作。

2.常用的方法

image-20210818210952676

package com.solider.filter;

import javax.servlet.*;
import java.io.IOException;

public class LifeFilter implements Filter {
    public LifeFilter() {
        System.out.println("构造方法!");
    }
    
    // 在启动服务器或者重新部署是执行
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化操作!");
    }

    // 每次请求都要执行一次
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("阻拦一起不合理的访问!");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    // 关闭服务器是执行
    @Override
    public void destroy() {
        System.out.println("销毁操作!");
    }
}

5、FilterConfig接口

1.基本概念

  • javax.servlet.FilterConfig接口主要用于描述过滤器的配置信息。

2.常用方法

image-20210818211055785

6、多个过滤器的使用

  • 如果有多个过滤器都满足过滤的条件,则容器依据映射的先后顺序来调用各个过滤器。

  •  <!-- 过滤器映射-->
        <filter-mapping>
            <filter-name>BFilter</filter-name>
            <url-pattern>*.avi</url-pattern>
        </filter-mapping>
    

image-20210818211126293

7、过滤器的优点

  • 实现代码的“可插拔性”,即增加或减少某个功能模块,不会影响程序的正常执行。
  • 可以将多个相同处理逻辑的模块集中写在过滤器里面,可实现重复利用、也方便代码的维护。

二、Listener监听器(重点)

1、基本概念

  • Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理。
  • 容器产生的事件分类如下:
    • 生命周期相关的事件。
    • 属性状态相关的事件。
    • 存值状态相关的事件。
  • 底层原理是采用接口回调的方式实现。

2、基本分类

image-20210818211431160

3、监听器详解

1.ServletRequestListener监听器

  • 在ServletRequest创建和关闭时都会通知ServletRequestListener监听器。
  • 常用方法如下:

image-20210818211527056

package com.soldier.listener;

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

public class MyRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("请求销毁了。。。。");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("创建请求。。。。");
    }
}

2.ServletRequestAttribute监听器

  • 向ServletRequest添加、删除或者替换一个属性的时候,将会通知ServletRequestAttributeListener监听器。
  • 常用方法如下:

image-20210818211615331

package com.soldier.listener;

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

public class MyRequestAttributeListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("增加了属性:" + servletRequestAttributeEvent.getName());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("属性" + servletRequestAttributeEvent.getName() + "被删除了!");
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("修改了属性:" + servletRequestAttributeEvent.getName());
    }
}

3.HTTPSessionListener监听器

  • 当一个HttpSession刚被创建或者失效(invalidate)的时候,将会通知HttpSessionListener监听器。
  • 常用方法如下:

image-20210818211700142

4.HTTPSessionAttributeListener监听器

  • HttpSession中添加、删除或者替换一个属性的时候,将会通知HttpSessionAttributeListener监听器。
  • 常用方法如下:

image-20210818211757686

5.ServletContectListener监听器

  • 在ServletContext创建和关闭时都会通知ServletContextListener监听器。
  • 常用方法如下:

image-20210818211850992

6.ServletContextAttributeListener监听器

  • 向ServletContext添加、删除或者替换一个属性的时候,将会通知ServletContextAttributesListener监听器
  • 常用方法如下:

image-20210818211952479

7.HTTPSessionBindingListener监听器

  • HttpSession中绑定和解除绑定时,将会通知HttpSessionListener监听器。
  • 常用方法如下:

image-20210818212040552

8.HTTPSessionActivationListener监听器

  • 当有session数值的钝化和活化操作时,将会通知HttpSessionActivationListener监听器。
    • 当服务器正常关闭时,还存活着的session(在设置时间内没有销毁) 会随着服务器的关闭被以文件(“SESSIONS.ser”)的形式存储在tomcat 的work 目录下,这个过程叫做Session 的钝化。
    • 当服务器再次正常开启时,服务器会找到之前的“SESSIONS.ser” 文件,从中恢复之前保存起来的Session 对象,这个过程叫做Session的活化。
  • 常用方法如下:

image-20210818212127712

  • 配置context.xml文件的方式如下:
<Manager className="org.apache.catalina.session.PersistentManager" 
saveOnRestart="true">
    <!-- 配置文件存放的路径信息,可以自由指定 -->
    <Store className="org.apache.catalina.session.FileStore" 
directory="C:\session"/>
</Manager>

4、实战案例

  • 自定义类实现监听器接口并重写相关的方法。
public class OnlineUser implements HttpSessionListener,ServletContextListener {
    ServletContext ctx = null;
    
    // 初始化ServletContext
    public void contextInitialized(ServletContextEvent e) {
         ctx = e.getServletContext();
         }
    // 销毁ServletContext
    public void contextDestroyed(ServletContextEvent e) {
         //将ServletContext设置成null;
    }
    // 当新创建一个HttpSession对象时
    public void sessionCreated(HttpSessionEvent e) {
        //将当前的在线人数加上1,并且保存到ServletContext(application)中
    }
    // 当一个HttpSession被销毁时(过期或者调用了invalidate()方法)
    public void sessionDestroyed(HttpSessionEvent e) {
        //将当前人数减去1,并且保存到ServletContext(application)中   
    }
}
  • 在web.xml中配置监听器
<listener>
    <listener-class> com.lagou.listener.OnlineUser </listener-class>
</listener>
package com.soldier.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class OnlineUser implements HttpSessionListener, ServletContextListener {

    // 声明一个ServletContext类型的引用负责作为全局对象来记录当前用户的数量,通过属性记录
    ServletContext servletContext = null;
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        servletContext = servletContextEvent.getServletContext();
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        servletContext = null;
    }

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("有新用户上线了...");
        Object count = servletContext.getAttribute("count");
        // 若当前用户为第一个用户,则将全局对象中的属性值设置为1即可
        if (null == count) {

            servletContext.setAttribute("count", 1);
        }
        // 若当前用户不是第一个用户,则将全局对象中原有的数据取出来加1后在设置进去
        else {
            Integer integer = (Integer)count;
            integer++;
            servletContext.setAttribute("count", integer);
        }
        System.out.println("当前在线用户数量为:" + servletContext.getAttribute("count"));
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("有用户已下线...");
    }
}

<%--
  Created by IntelliJ IDEA.
  User: Soldier
  Date: 2021/8/21
  Time: 15:36
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>显示当前在线用户的数量</title>
</head>
<body>
<h1>当前在线的人数为:${applicationScope.count}</h1>
</body>
</html>

posted on 2021-08-21 15:51  寒露凝珠  阅读(22)  评论(0编辑  收藏  举报

导航