一、用途

拦截器在我们的日常开发中有很重要的地位,可以帮我们完成很多重要的功能,比如登录认证、权限验证、记录日志和性能监控等。

二、自定义拦截器

SpringMVC中的所有拦截器都是实现自HandlerInterceptor接口,如果要编写一个自定义拦截器,我们就需要实现HandlerInterceptor接口或其子接口。

HandlerInterceptor源码如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.web.servlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;

public interface HandlerInterceptor {
    // 方法执行前被调用
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    // 方法执行后,视图渲染前被调用
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    // 视图渲染完成后被调用
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

自定义拦截器代码如下:

package com.example.springbootdemo.interceptor;

import lombok.extern.slf4j.Slf4j;
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;

/**
 * @author qx
 * @date 2023/07/16
 * @desc 自定义拦截器
 */
@Component
@Slf4j
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion");
    }
}

我们在3个方法中都打印了一条日志代码。

三、配置自定义拦截器

package com.example.springbootdemo.config;

import com.example.springbootdemo.interceptor.MyInterceptor;
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;

/**
 * @author qx
 * @date 2023/07/16
 * @desc WebMvc配置
 */
@Configuration
public class WebConfigurer implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加我们自定义的拦截器
        registry.addInterceptor(myInterceptor);
    }
}

三、创建测试的控制层

package com.example.springbootdemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author qx
 * @date 2023/07/16
 * @desc 控制层
 */
@RestController
public class IndexController {

    @GetMapping("/hello")
    public String hello() {
        return "hello interceptor";
    }
}

我们启动程序,并访问http://localhost:8080/hello,

我们在控制台看到如下输出:

2023-07-16 10:32:19.768  INFO 7560 --- [nio-8080-exec-4] c.e.s.interceptor.MyInterceptor          : preHandle
2023-07-16 10:32:19.771  INFO 7560 --- [nio-8080-exec-4] c.e.s.interceptor.MyInterceptor          : postHandle
2023-07-16 10:32:19.771  INFO 7560 --- [nio-8080-exec-4] c.e.s.interceptor.MyInterceptor          : afterCompletion

这代表我们的自定义拦截器成功了。

07-16 12:55