我有以下 @RestController
@RequestMapping(...)
public ResponseEntity(@RequestBody @Valid SomeDTO, BindingResult errors) {
//do something with errors if validation error occur
}
public class SomeDTO {
public SomeEnum someEnum;
}
如果 JSON 请求是 { "someEnum": "valid value"}
,一切正常。但是,如果请求是{ "someEnum": "invalid value"}
,它只会返回错误代码 400。
我如何捕获此错误以便提供自定义错误消息,例如“someEnum 的值必须为 A/B/C”。
最佳答案
@Amit 提供的答案很好并且有效。如果你想以特定方式反序列化枚举,你可以继续这样做。但该解决方案不可扩展。因为每个需要验证的枚举都必须使用 @JsonCreator
进行注释。
其他答案不会帮助您美化错误消息。
所以这是我的解决方案,适用于 spring web 环境中的所有枚举。
@RestControllerAdvice
public class ControllerErrorHandler extends ResponseEntityExceptionHandler {
public static final String BAD_REQUEST = "BAD_REQUEST";
@Override
public ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException exception,
HttpHeaders headers, HttpStatus status, WebRequest request) {
String genericMessage = "Unacceptable JSON " + exception.getMessage();
String errorDetails = genericMessage;
if (exception.getCause() instanceof InvalidFormatException) {
InvalidFormatException ifx = (InvalidFormatException) exception.getCause();
if (ifx.getTargetType()!=null && ifx.getTargetType().isEnum()) {
errorDetails = String.format("Invalid enum value: '%s' for the field: '%s'. The value must be one of: %s.",
ifx.getValue(), ifx.getPath().get(ifx.getPath().size()-1).getFieldName(), Arrays.toString(ifx.getTargetType().getEnumConstants()));
}
}
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setTitle(BAD_REQUEST);
errorResponse.setDetail(errorDetails);
return handleExceptionInternal(exception, errorResponse, headers, HttpStatus.BAD_REQUEST, request);
}
}
这将处理所有类型的所有无效枚举值,并为最终用户提供更好的错误消息。
示例输出:
{
"title": "BAD_REQUEST",
"detail": "Invalid enum value: 'INTERNET_BANKING' for the field: 'paymentType'. The value must be one of: [DEBIT, CREDIT]."
}
关于java - @RequestBody @Valid SomeDTO 有枚举类型的字段,自定义错误信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45968008/