SpringBoot项目Web拦截器使用的多种方式

2025-05-27 02:50

本文主要是介绍SpringBoot项目Web拦截器使用的多种方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《SpringBoot项目Web拦截器使用的多种方式》在SpringBoot应用中,Web拦截器(Interceptor)是一种用于在请求处理的不同阶段执行自定义逻辑的机制,下面给大家介绍Sprin...

在Spring Boot应用中,Web拦截器(Interceptor)是一种用于在请求处理的不同阶段执行自定义逻辑的机制。拦截器广泛应用于各种场景,以增强应用的功能性、安全性和可维护性。

在Spring Boot项目中实现Wen拦截器主要有以下几种方式

  • 实现 HandlerInterceptor 接口
  • 使用过滤器(Filter
  • 使用 @ASPect 注解实现AOP拦截

这里主要介绍 HandlerInterceptor 接口 和 Filter

一、实现 HandlerInterceptor 接口

这是最常见和直接的方式。需要创建一个类实现 org.springframework.web.servlet.HandlerInterceptor 接口,并重写其中的方法:

1、创建HandlerInterceptor实现类 MyInterceptor

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("preHandle");
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion");
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

2、注册拦截器

实现完拦截器后,需要将其注册到Spring MVC的配置中。可以通过继承 WebMvcConfigurer 接口并重写 addInterceptors 方法来完成:

import jakarta.annotation.Resource;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Resource
    private MyInterceptor myInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor)
                .addPathPatterns("/**")//拦截所有请求
                .excludePathPatterns("/login");// 放行登录请求
    }
}

这里的myInterceptor 也可以直接new MyInterceptor()

3、运行测试

MyInterceptor         : preHandle
MyInterceptor         : postHandle
MyInterceptor         : afterCompletion

二、使用过滤器(Filter)

虽然过滤器不属于拦截器的范畴,但在Spring Boot中,过滤器也是常用的请求处理组件。可以通过实现 Javax.servlet.Filter 接口来创建自定义过滤器:

1、创建过滤器实现类

这里我创建了3个测试过滤器,分别是 MyFilterMyFilter2MyFilter2,代码都是相同的,只是打印内容不一样

@Slf4j
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 请求前处理
        log.info("MyFilter doFilter pre");
        filterChain.doFilter(servletRequest, servletResponse);
        // 响应后处理
        log.info("MyFilter doFilter after");
    }
}

2、使用@Component 注解配置过滤器

通过将过滤器类声明为Spring组件,Spring Boot会自动检测并注册它。

import org.springframework.stereotype.Component;
@Component
public class MyFilter implements Filter {
    // 实现方法同上
}

注意:默认情况下,js使用@Component注册的过滤器会被添加到过滤链中,但顺序可能不确定。如果需要指定顺序,建议使用其他注册方式。

3、通过配置类注册过滤器(FilterRegistrationBean)

通过FilterRegistrationBean可以更灵活地注册过滤器,包括设置过滤器的顺序、URL模式等。

  • 可以精确控制过滤器的顺序。
  • 可以指定过滤器应IFoGHaCpu用的URL模式。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<MyFilter> myFilter() {
        FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new MyFilter());
        bean.addUrlPatterns("/*"); // 拦截所有请求
        bean.setOrder(1); // 设置过滤器顺序,数值越小优先级越高
        return bean;
    }
    @Bean
    public FilterRegistrationBean<MyFilter2> myFilter2() {
        FilterRegistrationBean<MyFilter2> bean = new FilterRegistrationBean<>();
        bean.setFilter(new MyFilter2());
        bean.addUrlPatterns("/*");
        bean.setOrder(2);
        return bean;
    }
    @Bean
    public FilterRegistrationBean<MyFilter3> MyFilter3() {
        FilterRegistrationBean<MyFilter3> bean = new FilterRegistrationBean<>();
        bean.setFilter(new MyFilter3());
        bean.addUrlPatterns("/*");
        bean.setOrder(3);
        return bean;
    }
}

运行测试

通过日志可以看见,order值越小优先级越高,过滤器的执行遵循先进后出的原则

c.hj.springboot3.filter.demo2.MyFilter   : MyFilter doFilter pre
c.hj.springboot3.filter.demo2.MyFilter2  : MyFilter2 doFilter pre
c.hj.springboot3.filter.demo2.MyFilter3  : MyFilter3 doFilter pre
c.h.s.filter.service.UserServiceImpl     : 执行业务代码
c.hj.springboot3.filter.demo2.MyFilter3  : MyFilter3 doFilter after
c.hj.springboot3.filter.demo2.MyFilter2  : MyFilter2 doFilter after
c.hj.springboot3.filter.demo2.MyFilter   : MyFilter doFilter after

三、使用OncePerRequestFilter

OncePerRequestFilter 是 Spring 框架提供的一个非常有用的过滤器基类,旨在确保某个过滤器在每个 HTTP 请求中只执行一次。这在需要确保某些处理逻辑(如身份验证、日志记录、请求修改等)在整个请求生命周期中不被重复执行时特别有用。

它的主要功能是确保其 doFilterInternal 方法在每个请求中仅被调用一次。这是通过检查请求属性来实现的,防止在某些情况下(如转发请求)过滤器被多次执行。

1. 主要方法

  • doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain):这是需要子类实现的方法,在其中编写自定义的过滤逻辑。该方法保证在每个请求中只被调用一次。
  • shouldNotFilter(HttpServletRequest request):可以重写此方法来指定某些请求不需要被过滤。
  • doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain):这是 Filter 接口的方法,OncePerRequestFilter 已经实现了该方法,确保 doFilterInternal 只执行一次。

2. 使用 OncePerRequestFilter

2.1 创建自定义过滤器

要使用 OncePerRequestFilter,通常需要创建一个继承自它的子类,并实现 doFilterInternal 方法。

示例代码:

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
public class CustomOncePerRequestFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                    HttpServletResponse response, 
                                    FilterChain filterChain)
            throws ServletException, IOException {
        // 请求预处理逻辑
        System.out.println("CustomOncePerRequestFilter: 请求前处理");
        // 继续过滤器链
        filterChain.doFilter(request, response);
        // 响应后处理逻辑
        System.out.println("CustomOncePerRequestFilter: 响应后处理");
    }
}

2.2 注册自定义过滤器

创建完自定义过滤器后,需要将其注册到 Spring Boot 应用中。可以使用 FilterRegistrationBean 进行注册。

示例代码:

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<CustomOncePerRequestFilter> customFilterRegistration() {
        FilterRegistrationBean<CustomOncePerRequestFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new CustomOncePerRequestFilter());
        registration.addUrlPatterns("/*"); // 拦截所有请求
        registration.setName("customOncePerRequestFilter");
        registration.setOrder(1); // 设置过滤器顺序
        return registration;
    }
}

四、其他类似过滤器

1、CharacterEncodingFilter

简介CharacterEncodingFilter 用于设置请求和响应的字符编码,确保请求参数和响应内容的编码一致,防止乱码问题。

使用场景:在处理国际化应用或需要特定字符编码的场景下非常有用。

示例配置

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
@Configuration
public class EncodingFilterConfig {
    @Bean
    public FilterRegistrationBean<CharacterEncodingFilter> characterEncodingFilter() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        filter.setForceEncoding(true);
        FilterRegistrationBean<CharacterEncodingFilter> registration = new FilterRegistrationBean<>(filter);
        registration.addUrlPatterns("/*");
        registration.setName("characterEncodingFilter");
        registration.setOrder(1);
        return registration;
    }
}

2、HiddenHttpMethodFilter

简介HiddenHttpMethodFilter 用于将带有特殊参数(如 _method)的 POST 请求转换为对应的 HTTP 方法(如 PUT、DELETE)。这在 html 表单不支持某些 HTTP 方法时非常有用。

使用场景:在使用 RESTful API 且前端仅支持 POST 请求时,通过隐藏字段指定实际的 HTTP 方法。

启用方式

在 Spring Boot 中,默认情况下,HiddenHttpMethodFilter 是启用的。如果需要自定义,可以手动注册:

@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
    return new HiddenHttpMethodFilter();
}

3、CorsFilter

简介CorsFilter 用于处理跨域资源共享(CORS)配置,允许或限制来自不同源的请求。

使用场景:在构建需要与前端分离的应用,且前端和后端部署在不同域时。

示例配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguraChina编程tion;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

到此这篇关于SpringBoot项目Web拦截器使用的文章就介绍到这了,更多相关SpringBoot Web拦截器内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文www.chinasem.cn章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于SpringBoot项目Web拦截器使用的多种方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154793

相关文章

golang float和科学计数法转字符串的实现方式

《golangfloat和科学计数法转字符串的实现方式》:本文主要介绍golangfloat和科学计数法转字符串的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望... 目录golang float和科学计数法转字符串需要对float转字符串做处理总结golang float

如何Python使用设置word的页边距

《如何Python使用设置word的页边距》在编写或处理Word文档的过程中,页边距是一个不可忽视的排版要素,本文将介绍如何使用Python设置Word文档中各个节的页边距,需要的可以参考下... 目录操作步骤代码示例页边距单位说明应用场景与高级用China编程途小结在编写或处理Word文档的过程中,页边距是一个

Logback在SpringBoot中的详细配置教程

《Logback在SpringBoot中的详细配置教程》SpringBoot默认会加载classpath下的logback-spring.xml(推荐)或logback.xml作为Logback的配置... 目录1. Logback 配置文件2. 基础配置示例3. 关键配置项说明Appender(日志输出器

linux lvm快照的正确mount挂载实现方式

《linuxlvm快照的正确mount挂载实现方式》:本文主要介绍linuxlvm快照的正确mount挂载实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux lvm快照的正确mount挂载1. 检查快照是否正确创建www.chinasem.cn2.

查看MySql主从同步的偏移量方式

《查看MySql主从同步的偏移量方式》:本文主要介绍查看MySql主从同步的偏移量方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 1.mysql的主从同步方案mysqlphp为了在实现读写分离,主库写,从库读mysql的同步方案主要是通过从库读取主库的binl

使用JavaConfig配置Spring的流程步骤

《使用JavaConfig配置Spring的流程步骤》JavaConfig是Spring框架提供的一种基于Java的配置方式,它通过使用@Configuration注解标记的类来替代传统的XML配置文... 目录一、什么是 JavaConfig?1. 核心注解2. 与 XML 配置的对比二、JavaConf

Maven项目打包时添加本地Jar包的操作步骤

《Maven项目打包时添加本地Jar包的操作步骤》在Maven项目开发中,我们经常会遇到需要引入本地Jar包的场景,比如使用未发布到中央仓库的第三方库或者处理版本冲突的依赖项,本文将详细介绍如何通过M... 目录一、适用场景说明​二、核心操作命令​1. 命令格式解析​2. 实战案例演示​三、项目配置步骤​1

使用Python和Tkinter实现html标签去除工具

《使用Python和Tkinter实现html标签去除工具》本文介绍用Python和Tkinter开发的HTML标签去除工具,支持去除HTML标签、转义实体并输出纯文本,提供图形界面操作及复制功能,需... 目录html 标签去除工具功能介绍创作过程1. 技术选型2. 核心实现逻辑3. 用户体验增强如何运行

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht

Spring Boot中的YML配置列表及应用小结

《SpringBoot中的YML配置列表及应用小结》在SpringBoot中使用YAML进行列表的配置不仅简洁明了,还能提高代码的可读性和可维护性,:本文主要介绍SpringBoot中的YML配... 目录YAML列表的基础语法在Spring Boot中的应用从YAML读取列表列表中的复杂对象其他注意事项总