java - Spring boot Rest 以空主体响应我的 @ControllerAdvice 中覆盖的异常以外的异常
问题描述
我有一个 @ControllerAdvice 扩展 ResponseEntityExceptionHandler 作为我尝试控制 API 调用工作流中引发的任何异常的标准响应。
没有控制器的建议。我得到了 spring 生成的基于 HTML 的通用响应,并带有正确的响应标头。但是当我添加我的@ControllerAdvice 时,Spring 不会以通用错误主体响应。正文为空且响应头正确
@Override
protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
String erroMessage = "Required Parameter: '"+ex.getParameterName()+"' was not available in the request.";
TrsApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, erroMessage, ex, ApiErrorCode.INVALID_REQUEST);
return buildResponseEntity(apiError);
}
因此,现在,如果请求中缺少必需的参数,流程会完美地触发我的重写实现,并使用描述错误的 JSON 有效负载进行响应。但是,如果出现任何其他异常,例如 HttpMediaTypeNotAcceptableException,spring 会以空主体响应。
在我添加我的建议之前,spring 以通用错误响应进行响应。我是 Spring Boot 生态系统的新手。需要帮助了解这是否是预期行为,是否有更好的方法来实现集中错误处理。
解决方案
我想我在 ControllerAdvice 类扩展时找到了吞下身体的解决方案ResponeEntityExceptionHandler
。在我的情况下,设置如下所示:
@ControllerAdvice
@Slf4j
class GlobalExceptionHandlers extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException exception,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
// logic that creates apiError object (object with status, message, errorCode, etc)
//...
return handleExceptionInternal(exception, apiError, headers, status, request);
}
这对于 class 的例外来说就像一个魅力MethodArgumentNotValidException
。但它破坏了由 处理的所有其他异常ResponseEntityExceptionHandler
,并为它们返回了空的响应正文。
但修复很简单,只需覆盖handleExceptionInternal
from ResponseEntityExceptionHandler
:
@ControllerAdvice
@Slf4j
class GlobalExceptionHandlers extends ResponseEntityExceptionHandler {
/// ... code from previous snippet
@Override
protected ResponseEntity<Object> handleExceptionInternal(
Exception exception,
Object body,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
// for all exceptions that are not overriden, the body is null, so we can
// just provide new body based on error message and call super method
var apiError = Objects.isNull(body)
? new ApiError(status, exception.getMessage()) // <--
: body;
return super.handleExceptionInternal(exception, apiError, headers, status, request);
}
}
推荐阅读
- angularjs - 安装离子应用程序脚本后,突然从节点模块中删除“@angular 文件夹”
- reactjs - React - Jest - Enzyme:如何模拟 ref 属性
- python - 山蟒的 3D 曲面图
- c++ - 用向量和迭代器 C++ 实现的通用快速排序
- unit-testing - 无法绑定到“routerDirection”,因为它不是“div”的已知属性
- javascript - 从自然节点的 wordnet 中获取同义词数组 - NodeJS
- r - R - 过滤行和求和
- c# - IEnumerable如何将项目添加到列表
- if-statement - VHDL 中的 if 语句:嵌套与多个条件
- android - 找不到属性 app:useSimpleSummaryProvider