锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. 【Spring Boot 拦截器介绍】

【Spring Boot 拦截器介绍】

0
  • 软件开发
  • 发布于 2024-08-16
  • 0 次阅读
黄健
黄健

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net

文章目录

  • 一、Spring Boot 拦截器是什么?
    • 1. 拦截器与过滤器的区别
      • 过滤器(Filter)
      • 拦截器(Interceptor)
  • 二、Spring Boot 拦截器的使用场景
    • 身份验证和授权
    • 日志记录
    • 性能监测
    • 通用行为的应用
  • 三、如何实现 Spring Boot 拦截器
    • 1. 创建拦截器类
    • 2. 注册拦截器
  • 四、高级配置
    • 1. 拦截器链
      • 配置拦截器链
    • 2. 动态拦截器
      • 实现动态拦截
    • 3. 异常处理
      • 在拦截器中处理异常

一、Spring Boot 拦截器是什么?

拦截器允许开发者在处理 HTTP 请求的生命周期的不同阶段—即请求处理之前、之后以及请求完成后—执行特定的操作。这些操作可以包括日志记录、身份验证、权限检查、事务管理等。

1. 拦截器与过滤器的区别

理解拦截器之前,有必要区分两个经常被混用的概念:拦截器(Interceptor)和过滤器(Filter)。

过滤器(Filter)

过滤器是 Java Servlet 规范的一部分,它在 Servlet 层面上提供了一种方式来处理请求和响应。过滤器可以对几乎所有的请求进行拦截,因为它们工作在请求的前端(在请求达到控制器之前)和后端(在响应被发送回客户端之前)。过滤器主要用于请求的预处理、响应的后处理,以及请求链中的请求 / 响应转换。

拦截器(Interceptor)

与过滤器相比,拦截器是 Spring MVC 提供的,它提供了更精细的控制。拦截器仅作用于处理器映射到的方法。这意味着,它们可以访问控制器执行的上下文,包括执行的控制器本身和控制器方法的元数据。拦截器可以在以下三个阶段执行操作:

  • preHandle:在 Controller 方法调用之前执行。可以进行身份验证、权限检查等操作,并决定是否中断执行链,即是否将请求传递给控制器处理。
  • postHandle:在 Controller 方法调用之后,但在视图被渲染之前执行。可以对模型数据进行操作或对视图进行处理。
  • afterCompletion:在整个请求结束后执行,即在视图渲染完毕后。这里可以进行资源清理等操作。

拦截器提供了一种更为灵活和强大的方式来插入跨越请求处理生命周期的逻辑。相比之下,过滤器更适合处理如请求日志记录、请求和响应的通用处理(比如设置响应头)等跨应用程序的共通行为。

二、Spring Boot 拦截器的使用场景

身份验证和授权

身份验证和授权是几乎每个应用必须处理的关键安全问题。通过拦截器,在请求到达目标控制器之前,可以检查用户的认证状态和权限。如果用户未经认证或缺乏访问特定资源的权限,拦截器可以阻止请求继续处理并直接返回一个错误响应或重定向到登录页面。这样的处理确保了应用的安全性,同时保持了控制器逻辑的清晰和专注。

日志记录

日志记录是开发和维护过程中的一个重要方面,它帮助开发者了解应用的运行状态,以及在出现问题时进行调试。通过拦截器,可以在请求处理的前后记录下请求路径、请求参数、用户身份等详细信息。这不仅有助于监控应用的健康状况,也为故障排查和性能分析提供了宝贵信息。

性能监测

在性能敏感的应用中,监测和优化请求的处理时间是提高用户体验的关键。拦截器可以用于监控请求的处理时间,通过记录请求开始和完成的时间,可以计算出处理每个请求所需的时间。这些数据可以用于识别性能瓶颈,指导后续的优化工作。

通用行为的应用

在多个控制器或请求处理流程中需要应用的通用行为,如跨域资源共享(CORS)设置、语言偏好处理、时区信息设置等,都可以通过拦截器以统一和非侵入式的方式实现。例如可以在拦截器中统一处理跨域请求的头信息,或根据请求头或参数调整语言和时区设置,从而提高代码的复用性和维护性。

三、如何实现 Spring Boot 拦截器

1. 创建拦截器类

首先需要定义一个类实现 HandlerInterceptor 接口或继承 HandlerInterceptorAdapter 类。这个接口定义了三个方法:preHandle、postHandle 和 afterCompletion,分别对应于请求处理的前、中、后三个阶段。

  • preHandle:在请求处理之前进行调用(Controller 方法调用之前)。这里可以进行权限验证、日志记录等操作。如果返回值为false,Spring MVC 将不会继续处理这个请求。
  • postHandle:在请求处理之后进行调用,但是在视图被渲染之前(Controller 方法调用之后)。可以通过这个方法对模型数据进行处理或对视图进行处理。
  • afterCompletion:在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要用于进行资源清理工作)。
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在Controller执行之前调用
        // 这里可以进行权限验证、日志记录等
        return true; // 返回true则继续执行下一个拦截器或处理器
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在Controller执行之后调用,但在视图渲染之前
        // 这里可以对模型数据进行处理或对视图进行处理
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在请求完全结束后调用,可用于清理资源等
    }
}

2. 注册拦截器

创建拦截器类之后,需要将其注册到 Spring MVC 的拦截器链中以启用其功能。可以通过实现 WebMvcConfigurer 接口并重写 addInterceptors 方法来完成。

在 WebMvcConfigurer 中可以定义拦截器的应用规则,比如指定拦截器应该拦截哪些 URL 路径。通过调用 InterceptorRegistry 的 addInterceptor 方法,并通过 addPathPatterns 方法来指定路径模式,可以非常灵活地配置拦截器的应用范围。

import org.springframework.beans.factory.annotation.Autowired;
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 {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册拦截器,并指定拦截的路径
        registry.addInterceptor(myInterceptor).addPathPatterns("/**");
        // 你也可以通过addPathPatterns添加多个匹配模式,或通过excludePathPatterns排除某些模式
    }
}

四、高级配置

1. 拦截器链

在 Spring Boot 应用中,可以通过配置多个拦截器来形成一个拦截器链。Spring MVC 会按照拦截器注册的顺序依次调用这些拦截器,执行它们的 preHandle、postHandle 和 afterCompletion 方法。

配置拦截器链

在 WebMvcConfigurer 的实现类中,可以通过调用 addInterceptors 方法多次添加多个拦截器,从而形成一个链。每个拦截器可以定义自己的拦截路径模式,也可以有共同的路径模式。

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new FirstInterceptor()).addPathPatterns("/**");
    registry.addInterceptor(new SecondInterceptor()).addPathPatterns("/api/**");
}

这个例子中,所有请求都会被 FirstInterceptor 拦截,而只有 /api/** 路径的请求会被 SecondInterceptor 拦截。

2. 动态拦截器

动态拦截器允许开发者根据请求的动态信息,如 URL、Header 等,来决定是否执行拦截器。可以通过在 preHandle 方法中添加逻辑来实现。

实现动态拦截

public class DynamicInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 根据请求的 URL 或 Header 决定是否进行拦截
        String headerValue = request.getHeader("X-Intercept");
        if ("true".equals(headerValue)) {
            // 执行某些操作
            return true; // 继续执行拦截器链
        } else {
            // 跳过当前拦截器,不对请求进行处理
            return false; // 中断执行,这将阻止控制器方法的执行
        }
    }
}

这个例子中,拦截器会检查请求头 X-Intercept 的值,根据这个值来决定是否进行后续操作。

3. 异常处理

在拦截器中处理异常

拦截器本身并不直接处理异常。相反,应当将异常信息传递给 Spring MVC 的异常处理机制。

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    if (ex != null) {
        // 记录异常信息,或者使用其他方式处理异常
        // 例如,可以将异常信息包装后抛出自定义异常
        throw new CustomException("Interceptor error", ex);
    }
}

在这个例子中,如果 afterCompletion 方法接收到异常,它会记录异常信息或抛出自定义异常。应用中应该有全局异常处理器(如使用 @ControllerAdvice 注解的类)来进一步处理这些异常,例如返回一个友好的错误响应给用户。

标签: #Spring Boot 173 #JAVA 991 #软件开发 1171
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.