在Jackson中使用ObjectMapper时验证JsonProperty中设置的(required = true)应该抛出异常

时间:2018-12-27 16:27:09

标签: java validation jackson jackson2 jackson-databind

我试图使用Jackson库进行反序列化,因为有一种情况,如果将JsonProperty设置为null,我必须验证许多JsonProperty中的required=true值。

这是代码段。

public class JacksonValidator {
    private static final ObjectMapper MAPPER = new ObjectMapper();

    public static void main(String[] args) {

        // Should succeed since all properties have value and required=true holds good
        validate("{\"id\": \"1\",\"age\": 26,\"name\": \"name1\"}");

        // Should throw exception since name is null (because of required=true)
        validate("{\"id\": \"2\",\"age\": 28,\"name\": null}");

        // Should throw exception since id is null (because of required=true)
        validate("{\"id\": null,\"age\": 27,\"name\": \"name2\"}");
    }

    public static void validate(String json) {

        try {
            Customer customer = MAPPER.readValue(json, Customer.class);
            System.out.println(customer);
        }
        catch (IOException e) {
            throw new DeserializationException(String.format("Validation failed. Unable to parse json %s", json), e);
        }
    }

    @Setter
    @Getter
    @ToString
    public static class Customer {
        private String id;
        private Integer age;
        private String name;

        @JsonCreator
        public Customer(@JsonProperty(value = "id", required = true) String id,
                @JsonProperty(value = "age", required = false) Integer age,
                @JsonProperty(value = "name", required = true) String name) {
            this.id = id;
            this.age = age;
            this.name = name;
        }
    }
}

如您在上面的代码中看到的,我正在尝试将JSON反序列化为Customer类。如果required的{​​{1}}属性设置为true,反序列化时如果该属性遇到JsonProperty(对于nullid字段上面的代码),我必须抛出一个自定义name

对于在JsonProperty(对于DeserializationException字段中设置了null的字段,我还需要处理required=false值(应该不会失败)。

在这里,我无法使用age,因为我需要处理MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL)字段的null值。

请让我知道如何使用required=false方法或此处适用的其他任何方法来实现此目的。

任何建议将不胜感激。

1 个答案:

答案 0 :(得分:1)

您不能使用@JsonProperty进行null验证。它仅检查值是否存在。来自javadocs

  

指示在反序列化期间属性是否期望值(可能为显式null)的属性。

对于null验证,可以使用Bean验证JSR-380。休眠示例:

Maven依赖项:

<!-- Java bean validation API - Spec -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

<!-- Hibernate validator - Bean validation API Implementation -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.11.Final</version>
</dependency>

<!-- Verify validation annotations usage at compile time -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator-annotation-processor</artifactId>
    <version>6.0.11.Final</version>
</dependency>

<!-- Unified Expression Language - Spec -->
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>3.0.1-b06</version>
</dependency>

<!-- Unified Expression Language - Implementation -->
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.el</artifactId>
    <version>2.2.6</version>
</dependency>

然后您可以像使用它一样

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Customer>> constraintViolations = validator.validate(customer);
if (constraintViolations.size() > 0) {
    throw new DeserializationException(String.format("Validation failed. Unable to parse json %s", json), e);
}