@controlleradvice搭配@exceptionhandler可实现全局异常统一处理,避免重复try-catch并统一返回json错误响应;支持按异常类型精准捕获、日志记录、参数校验异常处理及优先级控制。

在 Spring MVC 中,用 @ControllerAdvice 搭配 @ExceptionHandler 可以实现全局异常统一处理,避免每个 Controller 里重复写 try-catch,也方便统一返回格式(比如统一的 JSON 错误响应)。
基础用法:定义一个全局异常处理器类
新建一个类,加上 @ControllerAdvice 注解,它会自动对所有 @Controller 生效:
<font color="#888">@ControllerAdvice</font>
<font color="#0077aa">public</font> <font color="#0077aa">class</font> <font color="#6600cc">GlobalExceptionHandler</font> {
<font color="#888">@ExceptionHandler(NullPointerException.class)</font>
<font color="#0077aa">public</font> ResponseEntity<errorresponse> handleNullPoint(NullPointerException e) {
ErrorResponse error = <font color="#0077aa">new</font> ErrorResponse(<font color="#d14">"500"</font>, <font color="#d14">"空指针异常"</font>, e.getMessage());
<font color="#0077aa">return</font> ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
<font color="#888">@ExceptionHandler(UserNotFoundException.class)</font>
<font color="#0077aa">public</font> ResponseEntity<errorresponse> handleUserNotFound(UserNotFoundException e) {
ErrorResponse error = <font color="#0077aa">new</font> ErrorResponse(<font color="#d14">"404"</font>, <font color="#d14">"用户不存在"</font>, e.getMessage());
<font color="#0077aa">return</font> ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
}</errorresponse></errorresponse>
注意:@ControllerAdvice 默认作用于所有包下的 Controller;也可用 @ControllerAdvice(basePackages = "com.example.controller") 限定范围。
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
统一返回结构(推荐配合 @ResponseBodyAdvice)
如果希望所有接口(包括正常成功响应)都套一层统一格式(如 {"code":200,"msg":"ok","data":{...}}),可单独加一个 @ResponseBodyAdvice 做包装。但异常响应一般由 @ExceptionHandler 直接返回,所以重点还是把错误体设计好:
- 定义
ErrorResponse类,包含 code、message、timestamp、path 等字段 - 在
@ExceptionHandler方法中记录日志(建议用 SLF4J) - 区分业务异常(如参数校验失败、权限不足)和系统异常(如 NPE、数据库连接异常),分别处理
捕获参数校验异常(@Valid)
使用 @Valid 校验请求体时,抛出的是 MethodArgumentNotValidException,不是 BindException(后者用于 @ModelAttribute)。正确捕获方式:
<font color="#888">@ExceptionHandler(MethodArgumentNotValidException.class)</font>
<font color="#0077aa">public</font> ResponseEntity<errorresponse> handleValidation(MethodArgumentNotValidException e) {
String errorMsg = e.getBindingResult()
.getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(<font color="#d14">"; "</font>));
ErrorResponse error = <font color="#0077aa">new</font> ErrorResponse(<font color="#d14">"400"</font>, <font color="#d14">"参数校验失败"</font>, errorMsg);
<font color="#0077aa">return</font> ResponseEntity.badRequest().body(error);
}</errorresponse>
补充技巧与注意事项
- 多个
@ExceptionHandler方法支持继承关系匹配(例如捕获Exception可兜底所有未明确声明的异常) - 方法参数可以是
HttpServletRequest、HttpServletResponse、Exception或其子类,Spring 会自动注入 - 若同时存在多个
@ControllerAdvice,可用@Order控制优先级(数值越小优先级越高) - 确保该类被 Spring 扫描到(放在主启动类同包或子包下,或显式
@ComponentScan)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










