Spring MVC 拦截器入门

337 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情

前言

拦截器在我们的实际开发中是必不可少的,因为拦截器做的是一个权限控制的作用,这篇文章带大家了解下Spring MVC的拦截器。

拦截器简介

概念

拦截器,它是一种动态拦截方法的调用机制,在Spring MVC中动态的拦截控制器方法的执行。

作用

拦截器的作用它主要的作用是拦截指定的用户请求,并进行相应的预处理与后处理。其拦截的时间点在“处理器映射器根据用户提交的请求映射出了所要执行的处理器类,并且也找到了要执行该处理器类的处理器适配器,在处理器适配器执行处理器之前。”当然处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链,并返回给了中央调度器。

应用场景

  1. 日志记录:记录请求信息的日志。

  2. 权限检查:如登录检测。

  3. 性能监控:检测方法的执行时间。

  4. 通用行为:读取cookie得到用户信息并将用户对象放入请求。

简单实现拦截器

创建拦截器

首先我们在controller新建个包叫做interceptor用来管理我们的拦截器的类。

微信截图_20221022192705.png

然后,在interceptor包下创建interceptor类。

微信截图_20221022204716.png

在Spring MVC有对于拦截器的相关接口,我们只要实现相关的接口即可。

我们这里让interceptor类实现HandlerInterceptor接口并覆盖该接口的方法。

微信截图_20221022205437.png

我们这里覆盖了三个方法,来介绍下这三个方法分别起到个什么样的作用。

我们看方法名的英文单词应该也能猜出个大概。

preHandle:在拦截指定的用户的请求之前执行的一些操作。

postHandle:在拦截指定的用户的请求之后执行的一些操作。

afterCompletion:在拦截指定的用户的请求完成之后执行的一些操作。

preHandle方法返回值是一个boolean类型的返回值,默认为false,这个是起个什么样的作用呢?我们这里先卖个关子,后面再来讲。

我们在interceptor类的三个方法中都打印个相关方法的执行信息。

@Component
public class Interceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle执行");
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle执行");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion执行");
    }
}

配置SpringMvcSupportConfig

之后呢,我们去配置SpringMvcSupportConfig配置类。

@Configuration
public class SpringMvcSupportConfig extends WebMvcConfigurationSupport {
    @Autowired
    private Interceptor interceptor;

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor).addPathPatterns("/products");
    }
}

addInterceptors方法中我们添加了一个拦截器就是我们刚才创建的那个Interceptor然后添加了拦截路径为/products

然后我们启动tomcat服务器,并在Postman中来测试。

微信截图_20221022205310.png

查看我们的拦截器是否按照我们的预期进行了打印。

打印结果:

preHandle执行

为什么只执行了preHandle方法呢?这里就涉及到我们前面说的该方法的返回值。如果是false,拦截器将直接阻止被拦截请求的执行,所以后面的方法也是不会执行。所以我们这里要设置成true才可以。

改成true。

微信截图_20221022210009.png

然后重新启动服务器并使用Postman测试。

微信截图_20221022205201.png

preHandle执行
查询商品列表
postHandle执行
afterCompletion执行

这样就所有的方法都正确的打印出了信息。

总结

拦截器的入门就介绍到这里,之后的内容中,我们将介绍拦截器具体应用场景的使用。喜欢的小伙伴们多多支持,你们的支持就是我持续更新的动力。