想要了解拦截器在Servlet的声明周期的时间点 请查看:

Spring 拦截器(Interceptors)是Spring MVC框架的一部分,它提供了一种机制,允许你在请求到达Controller之前和响应返回给客户端之后进行处理。拦截器可以被用于多种场景,如日志记录、权限检查、事务管理等。

工作原理

Spring 拦截器基于Java Servlet的Filter接口实现。当一个请求被发送到Spring MVC应用时,它会通过一系列的拦截器,然后到达目标的Controller。Controller处理完请求后,响应也会通过这些拦截器返回给客户端。

拦截器链(Interceptor Chain)是由多个拦截器组成的,它们的执行顺序取决于它们在Spring配置中的声明顺序。

拦截器的主要方法

Spring 定义了HandlerInterceptor接口,它包含了三个主要的回调方法:

  1. preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):
    • 这个方法在Controller处理请求之前被调用。
    • 如果这个方法返回true,处理流程将继续;如果返回false,处理流程将停止,不会调用后续的拦截器和Controller。
  2. postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):
    • 这个方法在Controller处理请求之后,DispatcherServlet进行视图渲染之前被调用。
    • 可以通过修改ModelAndView来影响视图的渲染。
  3. afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex):
    • 这个方法在整个请求处理完毕,也就是视图渲染完毕之后被调用。
    • 可以用来进行资源清理。

当一个请求被拦截时,它会通过一系列的拦截器。每个拦截器都有机会决定是否要放行请求、处理请求或者是中止请求。如果一个拦截器决定中止请求,后续的拦截器将不会被调用。

在Spring中,拦截器链的执行依赖于每个拦截器的preHandle方法的返回值。如果preHandle返回true,则请求继续传递到下一个拦截器或者最终的处理器。如果preHandle返回false,则请求处理流程中断。

定义拦截器

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;

/**
 * @Author: zanglikun
 * @Date: 2022/5/7 18:43
 * @Description: 拦截器,实现HandlerInterceptor,然后重写方法
 */
@Slf4j
@Component // 可省略,但需要注册到WebMvcConfigurer
public class MyInterceptor implements HandlerInterceptor {

    /**
     * handler 参数的类型可以是以下几种:更多用于操作反射
     * HandlerMethod:代表一个控制器方法,包含方法的相关信息,如方法名、参数等。
     * HandlerInterceptor:代表一个拦截器,可以在请求处理前、处理后或渲染视图时执行一些操作。
     * ResourceHttpRequestHandler:代表一个处理静态资源的处理器,可以处理静态文件的请求。
     * WebSocketHandler:代表一个 WebSocket 处理器,用于处理 WebSocket 相关的请求。
     */
    // 请求拦截前处理
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 请求进来,会被拦截,这里可做日志打印,可获取所有请求参数。返回true 代表放行 返回false 代表拒绝请求。
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    //  Controller已经处理完毕了
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    // 结尾工作,如果preHandle方法内部(非Controller等后续有异常哈)抛出异常,本方法将不会触发,一般不过使用此方法
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

注册自定义拦截器

【教程】:创建MVCConfig类。实现WebMvcConfigurer,重写addInterceptor()方法即可!

注意:如果注册多个拦截器没有设置Order,那么先注册的先执行!如果都设定了Order那么Order越小优先执行!Order一样,估计就是按照拦截器名字为准了或注册的顺序!

请使用:

import XXXX.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

@Configuration
public class MVCConfig implements WebMvcConfigurer {

    @Resource
    private LoginInterceptor loginInterceptor;

    // 不支持Jrebel热部署,需要重启服务
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册一个拦截器,并放行/user下的接口
        registry.addInterceptor(loginInterceptor).order(0)
                .excludePathPatterns(
                        "/user/**",
                        "/.............."
                        );
    }
}

请废弃(经过投产使用时:发现@Value、@Resource 不可用)

原因:一开始我以为是低版本的Springboot版本导致的,经过测验,在实现WebMvcConfigurer的addInterceptors方法的时候,没有使用Sping创建的Bean管理,而是new出来的,肯定不会有@Value、@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 MVCConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册一个拦截器,并放行/user下的接口
        registry.addInterceptor(new MyInterceptor()).excludePathPatterns("/user/**").order(0);
    }
}
特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取全部资料 ❤