在自定义对象中包装默认 REST 错误响应
Wrapping default REST error response in custom object
我正在构建一个简单的 REST api 用于集成目的,我希望响应尽可能一致(无论错误如何都相同)。
我过去使用过 @ExceptionHandler
方法 - 所以我很可能会使用此方法的 class 版本...@ControllerAdvice
如果我没记错的话。
我知道它有效,我以前用过 SO 来帮助我,它只需要设置。 这不是我的问题...
API 允许创建消息和搜索消息(两个单独的请求),因此接受内部验证的日期值。对此进行测试后,我收到了一个格式非常漂亮且非常详细的错误响应:
{
"timestamp": "2018-08-31T10:35:10.748+0000",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"typeMismatch.IntegrationMessageFilter.fromDate",
"typeMismatch.fromDate",
"typeMismatch.java.util.Date",
"typeMismatch"
],
"arguments": [
{
"codes": [
"IntegrationMessageFilter.fromDate",
"fromDate"
],
"arguments": null,
"defaultMessage": "fromDate",
"code": "fromDate"
}
],
"defaultMessage": "Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'fromDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@com.fasterxml.jackson.annotation.JsonFormat java.util.Date] for value '213-456-45'; nested exception is java.lang.IllegalArgumentException",
"objectName": "IntegrationMessageFilter",
"field": "fromDate",
"rejectedValue": "213-456-45",
"bindingFailure": true,
"code": "typeMismatch"
}
],
"message": "Validation failed for object='IntegrationMessageFilter'. Error count: 1",
"path": "/Integration/get"
}
我想做的是拦截这个错误并将其包装在我自己的响应对象中,该对象对于每个可用的 API 方法都是相同的响应对象:
例如
{
"success": Boolean,
"messageId": Integer, (null on search, int on successful create)
"messages": Array, (searched IntegrationMessage objects)
"errorMessage": String, (error message during manual validation (e.g. range validation depending on the field))
"error" [SPRING DEFAULT ERROR] (this is what i want to intercept from spring-boot and include in this response object)
}
当系统已经创建详细的错误消息时,手动创建详细的错误消息似乎毫无意义......我不知道它使用什么对象创建上面的第一个 JSON 消息,或者即使我可以拦截它。
注意:这纯粹是为了方便API用户不用区分不同的响应对象,也方便我,不用重新-开发轮子(可以这么说)。
好的,我已经找到了实现(某种程度上)我想要的东西的方法。
我的印象是我可以拦截完整的异常响应消息并将其放入我的对象中,而不管异常的类型。事实证明,我可以获得 大多数 的默认信息,但它特定于每种错误类型(显然)。
第一次尝试:
我的第一次尝试是简单地 "test" 带有以下内容的默认错误响应。这是为了确定 spring 在做什么(它使用了哪个错误 - 我真的认为它会是 handleTypeMismatch
异常) - 下面的方法只是 class 中的一个(我目前正在处理的那个):
@ControllerAdvice
public class IntegrationExceptionHandler extends ResponseEntityExceptionHandler
{
@Override
public ResponseEntity<Object> handleBindException(final BindException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request)
{
return super.handleBindException(ex, headers, status, request);
}
}
我预计会出现与默认错误消息完全相同的错误消息,但是这没有产生任何响应(或空响应?)。
我的"Solution":
虽然我不必重新开发轮子,但我确实需要做一些跳环运动:
@Override
public ResponseEntity<Object> handleBindException(final BindException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request)
{
IntegrationResponse response = new IntegrationResponse(ex.getMessage());
response.setErrors(ex.getBindingResult().getAllErrors());
return new ResponseEntity<Object>(response, headers, status);
}
错误是 private List<ObjectError> errors;
(org.springframework.validation.ObjectError
)
所以我将不得不尝试复制 ResponseEntityExceptionHandler
中的每个可覆盖错误(适用于我的情况)并稍微不同地对待它,你现在可以明白我为什么只是想要包装现有的响应.
作为旁注,我确实尝试添加:private Object error;
和 private BindingResult error;
作为我的响应对象中的变量,但是这两种尝试似乎都拒绝了我的响应对象并仅显示默认消息(好像没有控制器建议),没有提示为什么。
如果有人确实发现了如何跳过 ResponseEntityExceptionHandler
步骤并只包装默认的异常响应对象,我会很乐意接受这个答案。
我正在构建一个简单的 REST api 用于集成目的,我希望响应尽可能一致(无论错误如何都相同)。
我过去使用过 @ExceptionHandler
方法 - 所以我很可能会使用此方法的 class 版本...@ControllerAdvice
如果我没记错的话。
我知道它有效,我以前用过 SO 来帮助我,它只需要设置。 这不是我的问题...
API 允许创建消息和搜索消息(两个单独的请求),因此接受内部验证的日期值。对此进行测试后,我收到了一个格式非常漂亮且非常详细的错误响应:
{
"timestamp": "2018-08-31T10:35:10.748+0000",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"typeMismatch.IntegrationMessageFilter.fromDate",
"typeMismatch.fromDate",
"typeMismatch.java.util.Date",
"typeMismatch"
],
"arguments": [
{
"codes": [
"IntegrationMessageFilter.fromDate",
"fromDate"
],
"arguments": null,
"defaultMessage": "fromDate",
"code": "fromDate"
}
],
"defaultMessage": "Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'fromDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@com.fasterxml.jackson.annotation.JsonFormat java.util.Date] for value '213-456-45'; nested exception is java.lang.IllegalArgumentException",
"objectName": "IntegrationMessageFilter",
"field": "fromDate",
"rejectedValue": "213-456-45",
"bindingFailure": true,
"code": "typeMismatch"
}
],
"message": "Validation failed for object='IntegrationMessageFilter'. Error count: 1",
"path": "/Integration/get"
}
我想做的是拦截这个错误并将其包装在我自己的响应对象中,该对象对于每个可用的 API 方法都是相同的响应对象: 例如
{
"success": Boolean,
"messageId": Integer, (null on search, int on successful create)
"messages": Array, (searched IntegrationMessage objects)
"errorMessage": String, (error message during manual validation (e.g. range validation depending on the field))
"error" [SPRING DEFAULT ERROR] (this is what i want to intercept from spring-boot and include in this response object)
}
当系统已经创建详细的错误消息时,手动创建详细的错误消息似乎毫无意义......我不知道它使用什么对象创建上面的第一个 JSON 消息,或者即使我可以拦截它。
注意:这纯粹是为了方便API用户不用区分不同的响应对象,也方便我,不用重新-开发轮子(可以这么说)。
好的,我已经找到了实现(某种程度上)我想要的东西的方法。
我的印象是我可以拦截完整的异常响应消息并将其放入我的对象中,而不管异常的类型。事实证明,我可以获得 大多数 的默认信息,但它特定于每种错误类型(显然)。
第一次尝试:
我的第一次尝试是简单地 "test" 带有以下内容的默认错误响应。这是为了确定 spring 在做什么(它使用了哪个错误 - 我真的认为它会是 handleTypeMismatch
异常) - 下面的方法只是 class 中的一个(我目前正在处理的那个):
@ControllerAdvice
public class IntegrationExceptionHandler extends ResponseEntityExceptionHandler
{
@Override
public ResponseEntity<Object> handleBindException(final BindException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request)
{
return super.handleBindException(ex, headers, status, request);
}
}
我预计会出现与默认错误消息完全相同的错误消息,但是这没有产生任何响应(或空响应?)。
我的"Solution":
虽然我不必重新开发轮子,但我确实需要做一些跳环运动:
@Override
public ResponseEntity<Object> handleBindException(final BindException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request)
{
IntegrationResponse response = new IntegrationResponse(ex.getMessage());
response.setErrors(ex.getBindingResult().getAllErrors());
return new ResponseEntity<Object>(response, headers, status);
}
错误是 private List<ObjectError> errors;
(org.springframework.validation.ObjectError
)
所以我将不得不尝试复制 ResponseEntityExceptionHandler
中的每个可覆盖错误(适用于我的情况)并稍微不同地对待它,你现在可以明白我为什么只是想要包装现有的响应.
作为旁注,我确实尝试添加:private Object error;
和 private BindingResult error;
作为我的响应对象中的变量,但是这两种尝试似乎都拒绝了我的响应对象并仅显示默认消息(好像没有控制器建议),没有提示为什么。
如果有人确实发现了如何跳过 ResponseEntityExceptionHandler
步骤并只包装默认的异常响应对象,我会很乐意接受这个答案。