【问题标题】:How to return a proper validation error for enum types in Spring Boot?如何在 Spring Boot 中为枚举类型返回正确的验证错误?
【发布时间】:2020-10-28 15:16:13
【问题描述】:

我创建了一个演示 spring boot 应用程序。该请求接受一个汽车对象并返回相同的对象。如果 carType 不是有效的枚举,我正在尝试找出一种向用户发送正确消息的方法。

请求

{
    "carType": "l"
}

回应

{
    "message": "JSON parse error: Cannot deserialize value of type `com.example.demo.Car$CarType` from String \"l\": not one of the values accepted for Enum class: [Racing, Sedan]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.example.demo.Car$CarType` from String \"l\": not one of the values accepted for Enum class: [Racing, Sedan]\n at [Source: (PushbackInputStream); line: 2, column: 13] (through reference chain: com.example.demo.Car[\"carType\"])",
    "statusCode": "BAD_REQUEST"
}

如何在不显示类名和堆栈跟踪的情况下向用户发送正确的消息?我希望用户知道枚举的有效类型是什么,但不希望消息具有 java 错误跟踪。有没有办法提取只有错误字段的正确消息。验证枚举的标准方法是什么?

Car.java

import lombok.*;

@Getter
@Setter
public class Car {
     enum CarType {
        Sedan,
        Racing
    }

    CarType carType;
}

DemoControllerAdvice.java

import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class DemoControllerAdvice {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ErrorObject handleJsonErrors(HttpMessageNotReadableException exception){

        return new ErrorObject(exception.getMessage(), HttpStatus.BAD_REQUEST);
    }
}

DemoController.java

@RestController
public class DemoController {

    @PostMapping("/car")
    public Car postMyCar(@RequestBody Car car){
        return car;
    }
    
}

是否有任何巧妙的方法可以使用 Hibernate Validator 但不使用下面的答案中的自定义 hibernate Validator? How to use Hibernate validation annotations with enums?

【问题讨论】:

  • 验证器无济于事,因为它甚至在此之前就失败了。 Jackson 无法将字符串转换为枚举,因为该值无效。

标签: java spring spring-boot hibernate enums


【解决方案1】:

没有。反序列化发生在验证之前。

如果你想让 Hibernate 这样做,那么you already linked to the answer。否则你必须自己处理异常。

private static final Pattern ENUM_MSG = Pattern.compile("values accepted for Enum class: \[([^\]])\]);"

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public ErrorObject handleJsonErrors(HttpMessageNotReadableException exception){
    if (exception.getCause() != null && exception.getCause() instanceof InvalidFormatException) {
        Matcher match = ENUM_MSG.matcher(exception.getCause().getMessage());
        if (match.test()) {
            return new ErrorObject("value should be: " + match.group(1),  HttpStatus.BAD_REQUEST);
        }
    }

    return new ErrorObject(exception.getMessage(), HttpStatus.BAD_REQUEST);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    相关资源
    最近更新 更多