Springboot3.x 进阶-拦截器

Spring Boot 3 拦截器概述

在Spring Boot 3中,拦截器(Interceptor)是框架内一个至关重要的组件,旨在请求处理的过程中提供一种机制来执行预处理和后处理逻辑。通过拦截器,开发人员可以在请求抵达控制器之前或之后插入特定的逻辑代码段,这使得它成为实现诸如用户认证、日志记录、性能分析等功能的理想选择。

拦截器的基础知识

拦截器作为Spring MVC架构的一部分,赋予了开发者在HTTP请求生命周期的不同阶段介入的能力。与Servlet容器级别的过滤器(Filter)相比,拦截器的工作更为深入,因为它紧密集成于Spring MVC的生命周期之中。这意味着拦截器能够获取更丰富的上下文信息,并对请求处理流程进行更加细致入微的控制。创建自定义拦截器可以通过实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter类来轻松完成。

拦截器的生命周期方法

Spring Boot 3环境中,拦截器提供了三个关键的方法以响应请求处理的不同阶段:

  1. preHandle():此方法会在实际的请求处理前被调用,适合用于执行前置操作如身份验证或权限检查等。如果preHandle()返回false,则意味着请求将被阻止,不会继续传递给下一个处理器。
  2. postHandle():一旦请求被处理完毕但在视图渲染发生之前,postHandle()会被触发。它为修改模型数据、添加额外的日志信息等操作提供了机会。
  3. afterCompletion():在整个请求处理结束之后,包括视图渲染完成后,会调用afterCompletion()。这一阶段常用来释放资源、记录最终的状态信息或统计性能指标等。

通过合理利用这些生命周期方法,开发者可以构建出功能强大且灵活的Web应用,同时确保代码的清晰性和可维护性。

实现一个拦截器

在Spring Boot 3中创建和使用拦截器通常涉及以下几个步骤:

1. 创建自定义拦截器

首先,你需要创建一个类来实现HandlerInterceptor接口或继承HandlerInterceptorAdapter(注意:从Spring Framework 5.3开始,HandlerInterceptorAdapter已被标记为过时,并将在未来的版本中移除)。实现HandlerInterceptor接口是推荐的方式。你将需要实现以下方法中的一个或多个:

  • boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):此方法在控制器处理请求之前调用。你可以在此处执行前置逻辑,如身份验证或权限检查。如果返回false,则中断请求的进一步处理。
  • void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):此方法在控制器处理之后但在视图渲染之前调用。可以用于修改模型数据或添加额外的日志信息。
  • void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex):此方法在整个请求处理完成后调用,包括视图渲染。常用于清理资源或记录性能数据。
package com.coderlk.interceptor.demo;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.util.LinkedHashMap;
import java.util.Map;

public class TokenInterceptor implements HandlerInterceptor {
    @Override
    /*
    * preHandle方法内部代码主要执行以下操作:
    * 1. 首先检查HTTP请求头中是否包含有效的token
    * 2. 如果token存在,则通过用户身份校验,请求可以继续处理;
    * 3. 如果token不存在,方法会构建一个错误信息响应,以JSON格式返回给客户端,并终止请求继续向下执行。
    * */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if(token != null) {
            return true;
        }else{
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String,String> result = new LinkedHashMap<>();
            result.put("code", "INVALID_TOKEN");
            result.put("message", "请求未包含Token,用户校验失败");
            response.setContentType("application/json;charset=utf-8");
            response.setStatus(401);
            response.getWriter().println(objectMapper.writeValueAsString(result));
            return false;
        }

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

2. 注册拦截器

接下来,你需要将你的拦截器注册到Spring MVC配置中。可以通过实现WebMvcConfigurer接口并重写addInterceptors方法来完成这一操作。这样做的好处是可以更灵活地指定哪些路径应该被拦截。

package com.coderlk.interceptor.demo;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class SpringWebConfiguration implements WebMvcConfigurer {

    /**
     * 注册拦截器并配置其拦截路径。
     *
     * @param registry 拦截器注册表,用于添加和管理拦截器。
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 创建一个TokenInterceptor实例并注册为拦截器
        InterceptorRegistration registration = registry.addInterceptor(new TokenInterceptor());


        // 配置该拦截器拦截所有路径
        registration.addPathPatterns("/**");

        // 配置该拦截器不拦截的路径,如静态资源路径
        registration.excludePathPatterns("/img/**", "/static/**");
    }

    /**
     * 添加资源处理器,用于处理静态资源请求。
     *
     * @param registry 资源处理器注册表,用于添加和管理资源处理器。
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 添加资源处理器,将"/static/**"路径的请求映射到"classpath:/static/"目录下的资源
        // 1.jpg -> url: http://localhost:8080/static/1.jpg
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }
}

3. 测试拦截器

最后一步是测试你的拦截器是否按预期工作。你可以通过发送HTTP请求给你的应用程序来验证拦截器的行为,确保它在正确的时间点执行了你期望的操作。

package com.coderlk.interceptor.demo;

import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @RequestMapping("/")
    public String test(@RequestHeader("token") String token){
        return "success";
    }
}

测试结果

### 失败
GET http://localhost:8080/
HTTP/1.1 401 
Content-Type: application/json;charset=utf-8
Content-Length: 77
Date: Fri, 13 Dec 2024 14:42:21 GMT
Keep-Alive: timeout=60
Connection: keep-alive

{
  "code": "INVALID_TOKEN",
  "message": "请求未包含Token,用户校验失败"
}

### 成功
GET http://localhost:8080/
Token: 213coiu423m

HTTP/1.1 200 
Content-Type: text/plain;charset=UTF-8
Content-Length: 7
Date: Fri, 13 Dec 2024 14:43:29 GMT
Keep-Alive: timeout=60
Connection: keep-alive

success

拦截器在Spring Boot 3中的应用场景

拦截器在Spring Boot 3中扮演着多面手的角色,适用于多种场景,有助于增强应用程序的功能和安全性。以下是拦截器的一些典型应用:

  • 身份验证与授权
    • 使用拦截器检查用户的身份验证状态和权限级别,确保只有经过验证且有适当权限的用户能够访问特定资源。这为应用程序的安全性提供了第一道防线。
  • 日志记录与审计
    • 在请求处理的不同阶段(如请求到达前、响应发送后)插入日志记录逻辑,帮助开发者跟踪系统行为、调试问题,并满足审计需求
  • 性能分析与监控
    • 拦截器可用于测量请求处理时间,收集性能指标,识别潜在的性能瓶颈,从而优化系统的响应速度和服务质量。
  • 跨域资源共享(CORS)配置
    • 当构建RESTful API时,通过拦截器设置适当的HTTP响应头来允许或限制跨域请求,简化前端与后端之间的交互。
  • 异常捕捉与友好错误处理
    • 捕获请求处理过程中抛出的异常,提供统一的错误处理机制,确保最终用户接收到格式化良好且友好的错误信息,而不是直接暴露底层技术细节
  • 数据预处理与后处理
    • 对进入的数据进行验证或转换,确保其符合预期格式;同时,在响应生成之后对输出数据进行格式化或加密等操作,以满足业务逻辑要求。
  • 流量控制与限流策略
    • 实施流量控制措施,例如限制同一IP地址在一定时间内发起的请求数量,或者控制并发请求的数量,以保护系统免受过载影响。

通过合理运用拦截器,开发人员可以在不改变原有业务逻辑的前提下,轻松地向应用程序添加这些额外的功能,提高系统的灵活性、安全性和可维护性。

注:各位亲爱的小伙伴们,今年是我从事软件行业的第20年,通过博客记录的方式将我知道的、理解的、有帮助的都分享给大家。同时,也提供就业指导,专业简历优化服务。你们的支持是我最大的动力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编码浪子

您的支持将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值