在我的 Spring Boot 项目中,我在@ControllerAdvice
中定义了一些@ExceptionHandler
类来处理特定的异常。它们构建特定于应用程序的 JSON 响应,而不是 Spring Boot 提供的默认值。到目前为止,这适用于例如在请求验证失败时抛出的MethodArgumentNotValidException
。
@ExceptionHandler(value = {MethodArgumentNotValidException.class})
public ResponseEntity<ApplicationResponse> handleValidationException(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
log.error("Validation failed: {}", errors);
return buildErrorResponse(ApplicationError.REQUEST_BODY_VALIDATION_FAILED, errors.toString(), HttpStatus.BAD_REQUEST);
}
对于我所知道的所有例外情况,这种方法对我来说似乎是合理的。但是,如果抛出不存在@ExceptionHandler
的异常,会发生什么情况?然后 Spring Boot 的默认值将启动,导致一个 JSON 响应,看起来与我的自定义响应不同。
我的第一个想法是为Exception
类添加一个@ExceptionHandler
,如下所示:
@ExceptionHandler(value = {Exception.class})
public ResponseEntity<ApplicationResponse> handleValidationException(Exception ex) {
log.error("An unhandled error occurred: {}", ex.getMessage());
return buildErrorResponse(ApplicationError.GENERIC_ERROR, HttpStatus.INTERNAL_SERVER_ERROR);
}
虽然这似乎有效,但我想知道这种方法是否可能有一些我不知道的主要缺点。对于可能发生的任何错误,您将如何使用自定义 JSON 结构进行响应?
Spring 有几种方法来处理异常处理程序,你可以在这里看到。将@ControllerAdvice
与多种@ExceptionHandler
一起使用具有以下优点:
- 集中式类,用于处理未捕获的异常。
- 自定义您希望如何管理特定内容。
关于包含@ExceptionHandler(value = {Exception.class})
来管理没有特定处理程序的异常,更好的选择是创建下一个:@ExceptionHandler(Throwable.class)
,这样您就可以管理应用程序中的所有潜在问题。
关于在应用程序中发生错误时返回 Json,您可以在响应本身中对其进行配置。例如:
private ResponseEntity<ErrorResponseDto> buildErrorResponse(RestApiErrorCode errorCode, List<String> errorMessages, HttpStatus httpStatus) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(APPLICATION_JSON);
ErrorResponseDto error = new ErrorResponseDto(errorCode, errorMessages);
return new ResponseEntity<>(error, headers, httpStatus);
}
您可以在此处查看其余代码