SpringMVC拦截器和异常处理器
拦截器
基本定义
- 拦截器(Interceptor)是一种强大的机制,允许在请求处理的不同阶段(如请求到达控制器之前、控制器处理请求之后、视图渲染之后)执行自定义逻辑。拦截器通常用于以下场景:
- 日志记录。
- 权限验证。
- 请求参数预处理。
- 性能监控等。
工作原理
-
Spring MVC 拦截器基于
HandlerInterceptor接口实现,它定义了三个方法,分别在请求处理的不同阶段执行:方法名 执行时机 preHandle在请求到达控制器之前执行。如果返回 false,则中断请求处理。postHandle在控制器处理请求之后、视图渲染之前执行。 afterCompletion在视图渲染之后执行,通常用于资源清理。
一定会执行即使是报错也一样特性 path="/"path="/**"匹配范围 仅匹配根路径 /匹配根路径 /和所有子路径
定义拦截器
-
要实现一个拦截器,需要实现
HandlerInterceptor接口,并重写其方法。 -
package com.example.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoggingInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Before handling the request: " + request.getRequestURI()); return true; // 继续处理请求 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, org.springframework.web.servlet.ModelAndView modelAndView) throws Exception { System.out.println("After handling the request: " + request.getRequestURI()); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("After rendering the view: " + request.getRequestURI()); } }
配置拦截器
-
可以通过 Java 配置类或 XML 配置文件来注册拦截器。
-
配置类
- 在配置类中实现
WebMvcConfigurer接口,并重写addInterceptors方法。
- 在配置类中实现
-
package com.example.config; import com.example.interceptor.LoggingInterceptor; 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 { @Override public void addInterceptors(InterceptorRegistry registry) { // 注册拦截器 registry.addInterceptor(new LoggingInterceptor()) .addPathPatterns("/**") // 拦截所有路径 .excludePathPatterns("/static/**"); // 排除静态资源 } } -
XML 配置文件
-
在 Spring配置文件中配置拦截器。
-
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <!-- 拦截所有路径 --> <mvc:exclude-mapping path="/static/**"/> <!-- 排除静态资源 --> <bean class="com.example.interceptor.LoggingInterceptor"/> </mvc:interceptor> </mvc:interceptors>
-
-
拦截器执行顺序
-
如果有多个拦截器,它们的执行顺序如下:
preHandle:按拦截器的注册顺序依次执行。- 按照拦截器的配置顺序依次执行。
- 如果某个拦截器的
preHandle方法返回false,则后续拦截器和处理器都不会执行,且会触发已执行拦截器的afterCompletion方法。
postHandle:按拦截器的注册顺序逆序执行。afterCompletion:按拦截器的注册顺序逆序执行。- 在
postHandle执行完毕后执行
- 在
-
改变执行顺序
-
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new FirstInterceptor()).order(1); registry.addInterceptor(new SecondInterceptor()).order(2); registry.addInterceptor(new ThirdInterceptor()).order(3); } } -
order值越小,优先级越高,即
FirstInterceptor的preHandle会先执行,postHandle和afterCompletion会后执行。
-
异常处理器
异常处理方式:Spring MVC 提供了以下几种方式来处理异常:
- 局部异常处理:使用
@ExceptionHandler注解在控制器内部处理异常。 - 全局异常处理:使用
@ControllerAdvice或@RestControllerAdvice注解定义全局异常处理器。 - 默认异常处理:通过实现
HandlerExceptionResolver接口自定义异常解析器。 - 默认的 Spring MVC 异常处理:Spring MVC 默认提供了
DefaultHandlerExceptionResolver和ResponseStatusExceptionResolver来处理常见异常。
局部异常处理:@ExceptionHandler
-
@ExceptionHandler注解用于在单个控制器中处理特定的异常。它可以定义在控制器方法中,用于捕获控制器内部抛出的异常。 -
@RestController public class MyController { @GetMapping("/test") public String test() { throw new RuntimeException("Test exception"); } // 处理控制器内部的 RuntimeException @ExceptionHandler(RuntimeException.class) public ResponseEntity<String> handleRuntimeException(RuntimeException ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error: " + ex.getMessage()); } } -
只能处理当前控制器中的异常。
-
支持多种异常类型,可以通过数组指定多个异常类,例如
@ExceptionHandler({RuntimeException.class, IOException.class})。
全局异常处理:@ControllerAdvice 和 @RestControllerAdvice
-
@ControllerAdvice和@RestControllerAdvice注解用于定义全局异常处理器,可以处理所有控制器中抛出的异常。-
@ControllerAdvice:适用于返回视图的控制器。 -
@RestControllerAdvice:适用于返回 JSON 或 XML 数据的 REST 控制器。 -
@RestControllerAdvice public class GlobalExceptionHandler { // 处理全局的 RuntimeException @ExceptionHandler(RuntimeException.class) public ResponseEntity<String> handleRuntimeException(RuntimeException ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Global Error: " + ex.getMessage()); } // 处理自定义异常 @ExceptionHandler(CustomException.class) public ResponseEntity<String> handleCustomException(CustomException ex) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Custom Error: " + ex.getMessage()); } } -
可以处理所有控制器中的异常。
-
支持定义多个异常处理方法。
-
可以通过
@ControllerAdvice(annotations = RestController.class)限定只处理特定注解的控制器。
-
自定义异常解析器:HandlerExceptionResolver
-
通过实现
HandlerExceptionResolver接口,可以自定义异常处理逻辑。Spring MVC 会调用resolveException方法来处理异常。 -
@Component public class CustomExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { if (ex instanceof CustomException) { ModelAndView mav = new ModelAndView(); mav.addObject("error", ex.getMessage()); mav.setViewName("error"); return mav; } return null; // 返回 null 表示继续调用其他异常处理器 } } -
可以完全控制异常处理逻辑。
-
适用于需要复杂处理的场景。
默认的 Spring MVC 异常处理
- Spring MVC 提供了两个默认的异常解析器:
DefaultHandlerExceptionResolver:- 处理 Spring MVC 内部抛出的标准异常,例如
HttpRequestMethodNotSupportedException、HttpMediaTypeNotSupportedException等。 - 返回标准的 HTTP 状态码。
- 处理 Spring MVC 内部抛出的标准异常,例如
ResponseStatusExceptionResolver:- 处理带有
@ResponseStatus注解的异常。 - 根据注解中的状态码返回 HTTP 响应。
- 处理带有

浙公网安备 33010602011771号