监听器,过滤器,拦截器

news2024/11/25 14:23:55

参考博文

文章目录

    • 作用
    • 三者区别
    • 启动顺序
    • 拦截器
      • 简要说明
      • 实现接口`HandlerInterceptor`
      • 自定义拦截器
      • 配置拦截器
    • 过滤器
      • 简要说明
      • 在springboot 启动类添加该注解@ServletComponentScan
      • 写个过滤器类,实现Filter接口
    • 监听器
      • 简要说明
      • 如何使用
        • 自定义事件
        • 自定义过滤器
        • 接口调用

作用

拦截器(interceptor):在一个请求进行中的时候,你想干预它的进展,甚至控制是否终止。这是拦截器做的事。
过滤器(Filter):当有一堆东西,只希望选择符合的东西。定义这些要求的工具,就是过滤器。
监听器(Listener):一个事件发生后,只希望获取这些事个事件发生的细节,而不去干预这个事件的执行过程,这就用到监听器

三者区别

拦截器(interceptor):依赖于web框架,基于Java的反射机制,属于AOP的一种应用。一个拦截器实例在一个controller生命周期内可以多次调用。只能拦截Controller的请求。

是在面向切面编程的就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

过滤器(Filter):依赖于Servlet容器,基于函数回掉,可以对几乎所有请求过滤,一个过滤器实例只能在容器初使化调用一次。

是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符.

监听器(Listener):web监听器是Servlet中的特殊的类,用于监听web的特定事件,随web应用启动而启动,只初始化一次。

Java的监听器,也是系统级别的监听。监听器随web应用的启动而启动。Java的监听器在c/s模式里面经常用到,它
会对特定的事件产生产生一个处理。监听在很多模式下用到,比如说观察者模式,就是一个使用监听器来实现的,在比如统计网站的在线人数。

过滤器监听器拦截器
关注的点web请求系统级别参数、对象部分web请求
如何实现函数回调事件java反射机制
应用场景设置字符编码,url级别权限访问,过滤敏感词汇,压缩响应信息统计网站在线人数,清除过期的
是否依赖servlet容器依赖不依赖
servlet提供的支持filterServletContextListener,HttpSessionListener
spring提供支持HandlerInterceptorAdapter,HandlerInterceptor
级别系统系统非系统

启动顺序

监听器,过滤器,拦截器

拦截器

简要说明

SpringBoot通过实现HandlerInterceptor接口实现拦截器,通过实现WebMvcConfigurer接口实现一个配置类,在配置类中注入拦截器,最后再通过@Configuration注解注入配置。

实现接口HandlerInterceptor

重写三个方法
preHandle 在请求处理之前进行调用(Controller方法调用之前)
postHandle 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
afterCompletion 整个请求结束之后被调用,也就是在DispatchServlet渲染了对应的视图之后执行(主要用于进行资源清理工作)

自定义拦截器

package com.geekmice.springbootselfexercise.interceptor;

import com.geekmice.springbootselfexercise.domain.UserDomain;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.interceptor
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  13:35
 * @Description: 登录拦截器
 * @Version: 1.0
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("登录拦截器前置处理");
        HttpSession session = request.getSession();
        UserDomain user = (UserDomain) session.getAttribute("user");
        if (Objects.nonNull(user)) {
            log.info("当前用户已登录,继续后面流程");
            return true;
        }else{
            log.info("未登录,请登录");
            response.sendRedirect(request.getContextPath() + "/user/login");
            throw new IllegalArgumentException("未登录,请登录");
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("request : [{}]", request);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("request : [{}]", request);
    }
}

配置拦截器

package com.geekmice.springbootselfexercise.config;

import com.geekmice.springbootselfexercise.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.config
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  13:47
 * @Description: 配置拦截器
 * @Version: 1.0
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getLoginInterceptor())
                .addPathPatterns("/**");
    }

    @Bean
    public LoginInterceptor getLoginInterceptor(){
        return new LoginInterceptor();
    }
}

在这里插入图片描述

过滤器

简要说明

使用过滤器很简单,只需要实现Filter类,然后重写它的3个方法即可。

init方法:程序启动调用Filter的init()方法(永远只调用一次);在容器中创建当前过滤器的时候自动调用这个方法。
destory方法:程序停止调用Filter的destroy()方法(永远只调用一次);在容器中销毁当前过滤器的时候自动调用这个方法。
doFilter方法:doFilter()方法每次的访问请求如果符合拦截条件都会调用(程序第一次运行,会在servlet调用init()方法以后调用;不管第几次,都在调用doGet(),doPost()方法之前)。这个方法有3个参数,分别是ServletRequest、ServletResponse和FilterChain可以从参数中获取HttpServletReguest和HttpServletResponse对象进行相应的处理操作。

在springboot 启动类添加该注解@ServletComponentScan

package com.geekmice.springbootselfexercise;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan
@MapperScan("com.geekmice.springbootselfexercise.dao")
public class SpringBootSelfExerciseApplication {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(SpringBootSelfExerciseApplication.class);
        springApplication.run(args);
    }

}

写个过滤器类,实现Filter接口

package com.geekmice.springbootselfexercise.filter;

import com.geekmice.springbootselfexercise.param.MyRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.filter
 * @Author: pingmingbo
 * @CreateTime: 2023-09-05  09:27
 * @Description: 修改分页参数默认值
 * @Version: 1.0
 */
@Configuration
@Slf4j
@WebFilter(filterName = "authFilter", urlPatterns = {"/tzArea"})
public class InitValueFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("过滤器开始初始化 : [{}]" , filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String pageSize = httpServletRequest.getParameter("pageSize");
        String pageNum = httpServletRequest.getParameter("pageNum");
        if(StringUtils.isAnyBlank(pageSize,pageNum)){
            pageSize="11";
            pageNum="1";
            Map<String,Object> map = new HashMap(16);
            map.put("pageSize", pageSize);
            map.put("pageNum", pageNum);
            MyRequestWrapper myRequestWrapper = new MyRequestWrapper(httpServletRequest, map);
            chain.doFilter(myRequestWrapper, response);
        }


    }

    @Override
    public void destroy() {
        log.info("过滤器销毁");
    }
}

监听器

简要说明

web监听器是一种 Servlet 中特殊的类,它们能帮助开发者监听 web 中特定的事件,比如 ServletContext, HttpSession, ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控。

如何使用

自定义事件

package com.geekmice.springbootselfexercise.event;

import com.geekmice.springbootselfexercise.domain.UserDomain;
import org.springframework.context.ApplicationEvent;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.event
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  15:17
 * @Description: 自定义事件
 * @Version: 1.0
 */
public class MyEvent extends ApplicationEvent {

    private UserDomain userDomain;

    public MyEvent(Object source, UserDomain userDomain) {
        super(source);
        this.userDomain = userDomain;
    }

    public UserDomain getUserDomain() {
        return userDomain;
    }

    public void setUserDomain(UserDomain userDomain) {
        this.userDomain = userDomain;
    }
}

自定义过滤器

package com.geekmice.springbootselfexercise.listener;

import com.geekmice.springbootselfexercise.domain.UserDomain;
import com.geekmice.springbootselfexercise.event.MyEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.listener
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  15:20
 * @Description: 自定义监听器,监听事件
 * @Version: 1.0
 */
@Slf4j
@Component
public class MyListener implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        // 获取事件中信息
        UserDomain userDomain = event.getUserDomain();
        // 用于逻辑处理
        log.info("userDomain : [{}]", userDomain);
    }
}

接口调用

package com.geekmice.springbootselfexercise.service.impl;

import com.geekmice.springbootselfexercise.domain.UserDomain;
import com.geekmice.springbootselfexercise.event.MyEvent;
import com.geekmice.springbootselfexercise.service.EventService;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.service.impl
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  15:25
 * @Description: 测试发布事件
 * @Version: 1.0
 */
@Service
public class EventServiceImpl implements EventService {
    @Resource
    private ApplicationContext applicationContext;

    @Override
    public void publishEvent() {
        UserDomain user = UserDomain.builder().userName("pmb").build();
        // 发布事件
        MyEvent myEvent = new MyEvent(this, user);
        applicationContext.publishEvent(myEvent);
        return;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1004036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图片怎么转换成pdf格式?几种方法轻松转换

图片怎么转换成pdf格式&#xff1f;将图片转换成PDF格式的主要原因是方便共享和存储。PDF格式可以在不同的设备和操作系统上轻松打开和查看&#xff0c;而且可以保持原始图片的质量和分辨率。如果你需要将一些图片转换成PDF格式&#xff0c;你可能会问&#xff0c;“该如何做呢…

12个最受欢迎的3D打印机械臂【开源|DIY|套件】

推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 机器人手臂的用途各不相同&#xff0c;但大多数都能够执行拾取和放置任务&#xff0c;而有些则配备用于 CNC 工作、激光雕刻&#xff0c;甚至 3D 打印。 机械臂具有广泛的应用和各个领域&#xff0c;从执行精密手术和进行工…

两行代码实现Redis消息队列,简单易用

Redis列表数据类型非常适合作为消息队列使用。将新的消息插入到列表尾部&#xff0c;然后从列表头部取出消息进行处理。该方案简单易用&#xff0c;并且支持多个消费者并行处理消息。 两行核心代码即可实现消息队列&#xff0c;如下&#xff1a; // 推送消息 redisTemplate.o…

Java中级编程大师班<第一篇:初识数据结构与算法-数组(2)>

数组&#xff08;Array&#xff09; 数组是计算机编程中最基本的数据结构之一。它是一个有序的元素集合&#xff0c;每个元素都可以通过索引进行访问。本文将详细介绍数组的特性、用法和注意事项。 数组的基本特性 数组具有以下基本特性&#xff1a; 有序性&#xff1a; 数…

初探词法分析实验

本次实验使用C对编译过程中的分词进行初步探究&#xff0c;以下是实验代码&#xff0c;输入文件需要在main函数中自己填写文本所在地址 #include <iostream> #include <stdlib.h> #include <stdio.h> #include<string> #define M 20 using namespace…

核心实验15_端口安全_ENSP

项目场景&#xff1a; 核心实验15_端口安全_ENSP 可指定该接口下最多接入几个设备&#xff08;通过mac绑定实现&#xff09;&#xff0c;人为增加设备时可设置接口自动down掉等&#xff0c;详见补充 实搭拓扑图&#xff1a; 具体操作&#xff1a; sw1: [Huawei]int g0/0/1 [H…

编辑视频无需第三方软件,在iPhone上也可以轻松编辑视频

如果你学会了如何在iPhone上编辑视频,你可以在很大程度上把匆忙拍摄的视频变成适合好莱坞的视频。好吧,也许这有点夸张了,但至少,你可以通过使用照片应用程序中的编辑工具,让你的视频看起来更令人印象深刻。 虽然它不一定能与最好的视频编辑软件相匹配,但它仍然非常适合…

MySQL 8.0 新密码策略的细节补充

前情提要 MySQL 8.0 截⽌到⽬前已经发布到了 8.0.34 版本&#xff0c;经过一系列的版本更新&#xff0c;对于密码方面也做了较多的加强⼯作&#xff0c;这⾥我们不再过多介绍 MySQL 8.0 对于密码功能的加强&#xff0c;相关的介绍可以移步先前公众号的⽂章&#xff0c;这⾥给到…

Pytorch 多卡并行(3)—— 使用 DDP 加速 minGPT 训练

前文 并行原理简介和 DDP 并行实践 和 使用 torchrun 进行容错处理 在简单的随机数据上演示了使用 DDP 并行加速训练的方法&#xff0c;本文考虑一个更加复杂的 GPT 类模型&#xff0c;说明如何进行 DDP 并行实战MinGPT 是 GPT 模型的一个流行的开源 PyTorch 复现项目&#xff…

paddleocr关闭log日志打印输出

问题背景 问题分析 可以看到paddleocr输出logging主要有两种&#xff0c;DEBUG和WARNING&#xff0c;因此关闭这两种打印日志即可。 解决方法 import logginglogging.disable(logging.DEBUG) # 关闭DEBUG日志的打印 logging.disable(logging.WARNING) # 关闭WARNING日志的…

Python二分查找详解

在计算机科学中&#xff0c;二分查找算法&#xff08;英语&#xff1a;binary search algorithm&#xff09;&#xff0c;也称折半搜索算法&#xff08;英语&#xff1a;half-interval search algorithm&#xff09;、对数搜索算法&#xff08;英语&#xff1a;logarithmic sea…

Pyinstaller打包EXE时添加版本信息、作者信息并在运行时读取外部配置文件

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;CSDN实力新星&#xff0c;后端开发两年经验&#xff0c;曾担任甲方技术代表&#xff0c;业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开…

亚马逊气候友好认证

“气候友好承诺认证”是亚马逊推出的Climate Pledge Friendly新环保计划。目的是帮助有环境意识、注重绿能的买家更好地找到带认证产品&#xff0c;品牌可以通过确保在亚马逊上销售的产品至少在可持续发展的一个方面得到认证&#xff0c;来参与并为他们的产品获得一个气候友好承…

ORA-32771 cannot add file to bigfile tablespace

ORA-32771 cannot add file to bigfile tablespace 扩容表空间报错 原因 oracle中有两种表空间类型BIGFILE 大文件表空间&#xff1a;只能包含1个大文件(最大尺寸为128 TB) SMALLFILE 小文件表空间&#xff1a;可包含多个数据文件(默认)表空间在创建的时候就会确定好&#xf…

OpenCV(三十八):二维码检测

1.二维码识别原理 功能图形&#xff1a; 位置探测图形&#xff1a;通常&#xff0c;二维码中有三个位置探测图形&#xff0c;呈现L型或大角度十字架形状&#xff0c;分布在二维码的三个角上&#xff0c;用于帮助扫描设备定位二维码的位置和方向。 位置探测图形分隔符&#xf…

2023工博会,正运动机器视觉运动控制一体机应用预览(二)

展会倒计时&#xff1a;7天 本次的中国国际工业博览会正运动技术将携高性能x86平台Windows实时视觉运动控制器VPLC711亮相。 •运动控制机器视觉一站式开发&#xff0c;缩短开发周期&#xff0c;降低硬件成本&#xff1b; •可替代传统的工控机运动控制卡/PLC视觉软件的自动化…

Fultter学习日志(2)-构建第一个flutter应用

依照上一篇中我们新建的flutter应用 让我们更改pubspec.yaml中的内容为 name: namer_app description: A new Flutter project.publish_to: none # Remove this line if you wish to publish to pub.devversion: 0.0.11environment:sdk: >2.19.4 <4.0.0dependencies:fl…

SpringBoot整合Easy-ES实现对ES操作

请确保已有可用的ES&#xff0c;若没有&#xff0c;请移步&#xff1a;Docker安装部署ElasticSearch&#xff08;ES&#xff09; 新建SpringBoot项目 这里是用的springboot版本是2.6.0 引入依赖 <!-- 排除springboot中内置的es依赖,以防和easy-es中的依赖冲突--><…

0基础学习VR全景平台篇 第99篇:百度地图如何上传全景图

蛙色平台现已打通VR全景入驻百度地图全流程&#xff0c;百度全景分为免费版和付费版两种&#xff0c;其中付费支持配置作品音乐、场景漫游热点、联系电话、描述信息。 百度地图上传案例 免费版 付费版 一、百度地图上传流程 1、进入蛙色VR账号后台 &#xff08;1&#xff…

Fiddler抓取HTTPS 详解

对于想抓取HTTPS的测试初学者来说&#xff0c;常用的工具就是fiddler。 但是初学时&#xff0c;大家对于fiddler如何抓取HTTPS难免走歪路&#xff0c;也许你一步步按着网上的帖子成功了&#xff0c;这自然是极好的。 但也有可能没那么幸运&#xff0c;这时候你就会很抓狂。 …