SpringMVC——拦截器

发布于:2025-03-18 ⋅ 阅读:(14) ⋅ 点赞:(0)

目录

拦截器概念

作用

入门拦截器

简化写法 

拦截器的执行流程

多拦截器


拦截器概念

    SpringMVC拦截器(Interceptor)是一种用于动态拦截请求处理流程的机制。它允许开发者在请求到达控制器(Controller)之前或响应返回给客户端之后,对请求和响应进行预处理和后处理。拦截器是AOP(面向切面编程)思想在Spring MVC中的具体实现之一。

作用

拦截器主要用于在请求处理流程中的特定点执行自定义逻辑,其作用包括但不限于:

  1. 权限验证:检查用户是否拥有访问某个资源的权限。
  2. 日志记录:记录请求和响应的详细信息,便于问题追踪。
  3. 请求预处理:在请求到达控制器之前对请求数据进行修改或补充。
  4. 响应后处理:在响应返回给客户端之前对响应数据进行修改或添加额外的头信息。

 拦截器和过滤器的区别

归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术

拦截内容不同:Filter对所有访问进行增强,Interceptor仅对SpringMVC的访问进行增强

 

入门拦截器

    在controller包下新建Interceptor包,在里面编写一个类,实现HandlerInterceptor接口,重写里面的三个方法

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Spring MVC拦截器,用于在请求处理的不同阶段执行特定操作。
 * 本拦截器通过实现HandlerInterceptor接口,提供了请求前处理、请求后处理以及请求完成后的回调方法。
 * 使用@Component注解声明为Spring管理的组件,会自动被Spring容器检测并注册为拦截器。
 */
@Component
public class ProjectInterceptor implements HandlerInterceptor {

    /**
     * 在请求处理之前执行(Controller方法调用之前)
     * @param request  HTTP请求对象
     * @param response HTTP响应对象
     * @param handler  被调用的处理器对象
     * @return boolean 返回true表示继续流程,返回false则中断流程
     * @throws Exception 可能抛出的异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("perHandle...");
        return true;
    }

    /**
     * 在整个请求处理完成后执行(视图渲染结束后)
     * 主要用于资源清理、统计信息收集等收尾工作
     * @param request  HTTP请求对象
     * @param response HTTP响应对象
     * @param handler  被调用的处理器对象
     * @param ex       处理过程中抛出的异常(如果有)
     * @throws Exception 可能抛出的异常
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }

    /**
     * 在请求处理之后,视图渲染之前执行(Controller方法调用之后)
     * @param request      HTTP请求对象
     * @param response     HTTP响应对象
     * @param handler      被调用的处理器对象
     * @param modelAndView 模型和视图对象,可用于修改模型数据或视图(可为null)
     * @throws Exception 可能抛出的异常
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }
}

    在配置包下创建类,继承WebMvcConfigurationSupport,重写addResourceHandlers

 和addInterceptors

import com.cc.controller.interception.ProjectInterceptor;
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.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

/**
 * Spring MVC 配置类,用于自定义Web配置
 * 继承WebMvcConfigurationSupport类可覆盖默认的MVC配置
 * 注意:在Spring Boot项目中,更推荐实现WebMvcConfigurer接口替代继承此类
 */
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    private ProjectInterceptor projectInterceptor;  //注入拦截器

    /**
     * 配置静态资源处理
     * 将/pages/**路径的请求映射到类路径下的/pages目录
     * @param registry 资源处理器注册器,用于管理静态资源路径映射
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        //过滤访问静态资源
        // 注册projectInterceptor拦截器,并设置拦截路径
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages");
    }

    /**
     * 注册自定义拦截器并配置拦截规则
     * @param registry 拦截器注册器,用于管理请求拦截规则
     */
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/users","/users/*");
    }
}

接下来尝试发送请求:

说明拦截器可以在方法的前和后增强方法。

再次发送请求

 并没有被拦截,原因是:

 添加拦截路径即可:

 

简化写法 

    前面新建了SpringMVC配置类,继承的是WebMvcConfigurationSupport,该部分可以直接写在SpringMVC配置类中,实现WebMvcConfigurer接口,重写addInterceptor方法

@Configuration
@ComponentScan({"com.cc.controller"})  //不加载SpringMvcSupport
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ProjectInterceptor projectInterceptor;

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

拦截器的执行流程

多拦截器

    当配置多个拦截器时,会形成拦截器链。

直接复制前面写的拦截器,修改,并对它进行配置:

重新发送请求,就可以观察到拦截器的执行顺序:

由此可得拦截器的执行顺序:

  • 拦截器的运行顺序参照拦截器的添加顺序为准
  • 执行了controller后执行的顺序相反
  • 当拦截器出现对原始数据的拦截,后面的拦截器均会终止运行
  • 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作