HandlerInterceptor 接口详解
1. 接口方法说明
方法 | 作用 | 执行时机 | 返回值/注意事项 |
---|---|---|---|
preHandle | 请求处理前拦截 | 在控制器方法执行前调用 | 返回 false 中断后续流程;返回 true 继续执行 |
postHandle | 控制器方法执行后拦截 | 在控制器方法返回结果后,视图渲染前调用 | 无返回值,不可中断流程 |
afterCompletion | 请求完全结束后拦截 | 在视图渲染完成后调用(无论是否成功) | 无返回值,用于资源清理 |
2. 完整示例代码
2.1 自定义拦截器A(返回 false)
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
public class InterceptorA implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {System.out.println("InterceptorA.preHandle: 开始拦截请求");// 返回 false 中断请求流程return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {System.out.println("InterceptorA.postHandle: 此处不会执行(因 preHandle 返回 false)");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println("InterceptorA.afterCompletion: 请求已中断,但此方法仍会被调用");}
}
2.2 自定义拦截器B(正常流程)
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
public class InterceptorB implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {System.out.println("InterceptorB.preHandle: 正常拦截");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {System.out.println("InterceptorB.postHandle: 控制器方法执行后");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println("InterceptorB.afterCompletion: 请求完成");}
}
2.3 注册拦截器配置
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 WebConfig implements WebMvcConfigurer {@Autowiredprivate InterceptorA interceptorA;@Autowiredprivate InterceptorB interceptorB;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册顺序:A 先于 Bregistry.addInterceptor(interceptorA).addPathPatterns("/**");registry.addInterceptor(interceptorB).addPathPatterns("/**");}
}
2.4 控制器示例
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {@GetMapping("/test")public String test() {System.out.println("控制器方法执行:此请求将被拦截器A中断");return "Hello World";}
}
3. 输出结果分析(访问 /test
)
InterceptorA.preHandle: 开始拦截请求
InterceptorA.afterCompletion: 请求已中断,但此方法仍会被调用
- 拦截器A的
preHandle
返回false
后:- 拦截器B的
preHandle
不会被调用。 - 控制器方法不会执行。
- 拦截器B的
postHandle
和afterCompletion
也不会执行。 - 拦截器A的
afterCompletion
仍会被调用(因已进入拦截器链)。
- 拦截器B的
4. 常见处理场景示例
在拦截器中可实现以下功能:
- 日志记录:记录请求时间、URL、IP 等(如示例中的
System.out.println
)。 - 权限校验:检查用户登录状态或角色权限。
- 性能监控:计算接口响应时间。
- 请求参数预处理:统一处理请求参数(如解密、格式化)。
5. 拦截器执行顺序总结表
阶段 | 执行顺序规则 | 示例(A注册在 B 前) |
---|---|---|
preHandle | 按注册顺序依次执行 | A → B |
postHandle | 按注册逆序依次执行 | B → A |
afterCompletion | 按注册逆序依次执行 | B → A |
注意:若某个
preHandle
返回false
,后续拦截器和控制器方法均被跳过,但已执行的拦截器的afterCompletion
仍会执行。