java - @RequestBody @Valid SomeDTO 有枚举类型的字段,自定义错误信息

标签 java spring rest validation

我有以下 @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/

相关文章:

java - 有没有办法在Java中的抽象接口(interface)方法中要求特定值作为参数?

java - 如何在 mapstruct 中使用来自不同类的另一个映射

java - Flyway使用java类对sql文件进行排序

spring - 什么是属性 management.health.redis.enabled 以及如何使用它?

java - 如何从 SQL 中的两个表中获取匹配的行,而无需从 java 中重复调用

java - 使用 modelAttribute 提交表单时在 Spring MVC 中上传多个文件时出现 400 错误请求

java - CouchDb - MongoDb 和 NoSQL 数据库比较(使用 XML 文档)

ios - 从 Swift 函数中的异步调用返回数据

java - 当java中的响应代码为4xx时,如何解析REST API的响应正文

java - 如何使用 CMIS REST API 访问 Alfresco 中的文件?