spring mvc中如何对所有Controller进行拦截呢?
下文笔者讲述springmvc中对所有Controller进行拦截的方法及示例分享,如下所示
2.使用`@ControllerAdvice`
所有Controller拦截的实现思路
方式1: 使用`HandlerInterceptor`实现拦截器 方式2: 使用`@ControllerAdvice` 或 `@RestControllerAdvice` 方式3: 使用Filter(Servlet 过滤器) 方式4: 使用AOP(面向切面编程)
1.使用`HandlerInterceptor`实现拦截器
步骤如下:(1)创建一个拦截器类 @Component public class GlobalInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在 Controller 方法执行前调用 System.out.println("Before Controller: " + request.getRequestURI()); return true; // 返回 false 表示中断请求 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // Controller 方法执行后,视图渲染前调用 System.out.println("After Controller, before view rendered."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 整个请求完成后调用(包括异常情况) System.out.println("Request completed."); } } (2)注册拦截器 如果是Spring Boot项目 创建配置类注册拦截器: @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private GlobalInterceptor globalInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(globalInterceptor) .addPathPatterns("/**") // 拦截所有请求 .excludePathPatterns("/static/**", "/error"); // 排除某些路径 } }
2.使用`@ControllerAdvice`
或
`@RestControllerAdvice`
适用于全局异常处理、数据绑定等场景,但不能拦截请求流程本身 @RestControllerAdvice public class GlobalControllerAdvice { @ModelAttribute public void logRequest(HttpServletRequest request) { System.out.println("Request URL: " + request.getRequestURL()); } }
3.使用Filter(Servlet过滤器)
Filter 更底层的拦截机制 作用于更早阶段(甚至可以拦截静态资源) 例: @Component public class GlobalFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; System.out.println("Filter: Request URI = " + req.getRequestURI()); chain.doFilter(request, response); // 继续后续流程 } }
4.使用AOP(面向切面编程)
如果你需要基于方法级别的拦截(如所有 `@RequestMapping` 注解的方法),可以使用 Spring AOP。 @Aspect @Component public class ControllerAspect { @Pointcut("execution(* com.example.controller..*.*(..))") public void controllerMethods() {} @Before("controllerMethods()") public void before(JoinPoint joinPoint) { System.out.println("AOP Before Method: " + joinPoint.getSignature().getName()); } @AfterReturning(pointcut = "controllerMethods()", returning = "result") public void afterReturning(JoinPoint joinPoint, Object result) { System.out.println("AOP After Returning: " + result); } }
各种拦截方法对比
方式 | 是否能拦截 Controller | 能否获取 Request/Response | 是否支持路径匹配 | 是否推荐用于全局拦截 |
`HandlerInterceptor` | ✅ | ✅ | ✅ | ✅ 强烈推荐 |
`@ControllerAdvice` | ❌(仅能处理 ModelAttribute、异常等) | ✅ | ❌ | 否 | |
`Filter` | ✅(但无法获取 Controller 信息) | ✅ | ✅ | 否 |
`AOP` | ✅ | ❌(难以获取完整上下文) | ✅(通过包路径) | 可选 |
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。