首页 > 编程笔记

Spring Boot Interceptor(拦截器)详解

Interceptor(拦截器)这一功能由 Spring 提供。Interceptor 与 Filter 类似,操作粒度更小,但整体功能不如 Filter 强大。Interceptor 支持自定义预处理(preHandle)可以在此过程中决定是否禁止程序继续进行,自定义后续处理(postHandle)。其处理流程如图 1 所示。

图1 Interceptor工作流程示意图
图1 Interceptor工作流程示意图

使用拦截器的前提是需要实现 HandlerInterceptor 接口。该接口包含三种主要方法:

使用拦截器记录请求参数

首先创建一个继承 HandlerInterceptorAdapter 的拦截器类,使用日志打印请求中的参数。在路径 src/main/java/com/example/myblog/interceptor 下创建 LogRequestInterceptor.java:
@Slf4j
@Component
public class LogRequestInterceptor extends HandlerinterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info(String.format("[preHandle][%s][%s]%s%s", request, request.getMethod(), request.getRequestURI(), getParameters(request)));
        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 {
        if (ex != null) {
            ex.printStackTrace();
        }
        log.info(String.format("[afterCompletion] [%s] [exception:%s]", request, ex));
    }

    //提取请求中的参数
    private String getParameters(HttpServletRequest request) {
        StringBuilder parameterBuilder = new StringBuilder();
        Enumeration<String> names = request.getParameterNames();
        if (names != null) {
            parameterBuilder.append("?");
            while (names.hasMoreElements()) {
                if (parameterBuilder.length() > 1) {
                    parameterBuilder.append("&");
                }
                String pointer = names.nextElement();
                parameterBuilder.append(pointer).append("=").append(request.getParameter(pointer));
            }
        }
        return parameterBuilder.toString();
    }
}
然后将拦截器配置到 Spring 上下文。在路径 src/main/java/com/example/myblog/config 下创建 InterceptorConfig.java:
@Configuration
@RequiredArgsConstructor
public class InterceptorConfig implements WebMvcConfigurer {

    private final LogRequestInterceptor logRequestInterceptor;

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

优秀文章