Spring Boot能否用单个@ExceptionHandler处理多个自定义异常?
问题
现有一段通过@ControllerAdvice实现的全局异常处理代码,功能正常但冗余严重。代码针对CustomException1、CustomException2、CustomException3分别编写了独立的@ExceptionHandler方法,逻辑高度相似,仅错误码和HttpStatus不同。所有自定义异常都继承自RuntimeException,希望用单个@ExceptionHandler统一处理这些自定义异常。
原异常处理器代码:
@ControllerAdvice public class HandleExceptions { @ExceptionHandler(value = CustomException1.class) public ResponseEntity<Object> handleCustomException1(CustomException1 e) { HttpStatus status = HttpStatus.NOT_FOUND; DataResponse data = new DataResponse("custom status code for exception 1", e.getMessage()); ExceptionResponse exceptionResponse = new ExceptionResponse(data); return new ResponseEntity<>(exceptionResponse, status); } @ExceptionHandler(value = CustomException2.class) public ResponseEntity<Object> handleCustomException2(CustomException2 e) { HttpStatus status = HttpStatus.NOT_FOUND; DataResponse data = new DataResponse("custom status code for exception 2", e.getMessage()); ExceptionResponse exceptionResponse = new ExceptionResponse(data); return new ResponseEntity<>(exceptionResponse, status); } @ExceptionHandler(value = CustomException3.class) public ResponseEntity<Object> handleCustomException3(CustomException3 e) { HttpStatus status = HttpStatus.BAD_REQUEST; DataResponse data = new DataResponse("custom status code for exception 3", e.getMessage()); ExceptionResponse exceptionResponse = new ExceptionResponse(data); return new ResponseEntity<>(exceptionResponse, status); } }
相关实体类:
public class ExceptionResponse { private final DataResponse data; // 构造方法、Getter省略 } public class DataResponse { private String statusCode; private String message; // 构造方法、Getter/Setter省略 }
原自定义异常基类:
public class CustomException extends RuntimeException{ public CustomException(String message){ super(message); } }
期望响应示例:
{ "data": { "statusCode": "1111", "message": "user not found" } }
解决方案
核心思路是让每个自定义异常自身携带对应的错误码和HttpStatus属性,通过统一的基类处理器提取这些属性并生成响应。
1. 改造自定义异常基类
给基类添加错误码和Http状态的属性,通过构造方法注入:
import org.springframework.http.HttpStatus; public class CustomException extends RuntimeException { private final String statusCode; private final HttpStatus httpStatus; public CustomException(String message, String statusCode, HttpStatus httpStatus) { super(message); this.statusCode = statusCode; this.httpStatus = httpStatus; } // Getter方法 public String getStatusCode() { return statusCode; } public HttpStatus getHttpStatus() { return httpStatus; } }
2. 定义具体自定义异常类
每个具体异常只需继承基类,在构造时传入专属的错误码和Http状态:
import org.springframework.http.HttpStatus; public class CustomException1 extends CustomException { public CustomException1(String message) { super(message, "custom status code for exception 1", HttpStatus.NOT_FOUND); } } public class CustomException2 extends CustomException { public CustomException2(String message) { super(message, "custom status code for exception 2", HttpStatus.NOT_FOUND); } } public class CustomException3 extends CustomException { public CustomException3(String message) { super(message, "custom status code for exception 3", HttpStatus.BAD_REQUEST); } }
3. 编写统一异常处理器
只用一个@ExceptionHandler处理基类CustomException,从异常实例中提取配置并构建响应:
import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @ControllerAdvice public class HandleExceptions { @ExceptionHandler(value = CustomException.class) public ResponseEntity<Object> handleCustomException(CustomException e) { DataResponse data = new DataResponse(e.getStatusCode(), e.getMessage()); ExceptionResponse exceptionResponse = new ExceptionResponse(data); return new ResponseEntity<>(exceptionResponse, e.getHttpStatus()); } }
4. 验证效果
抛出任意具体自定义异常时,处理器会自动获取对应的错误码和Http状态,生成符合要求的响应。例如抛出CustomException1时,响应结构如下:
{ "data": { "statusCode": "custom status code for exception 1", "message": "user not found" } }
内容的提问来源于stack exchange,提问作者brain-dot-isEmpty
相关产品推荐
相关产品推荐

