简体   繁体   中英

Validating (required=true) set in JsonProperty while using ObjectMapper in Jackson should throw Exception

I am trying to use Jackson library for deserialization since I have a scenario wherein I have to validate for null values in many JsonProperty if it is set as required=true .

Here is the code snippet.

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;
        }
    }
}

As you can see in the above code, I am trying to deserialize JSON into Customer class. If the required property is set to true for a JsonProperty and while deserialization if this property encounters null (for id and name field in the above code), I have to throw a custom DeserializationException .

And also I need to have null values processed(shouldn't fail) for fields where required=false is set in JsonProperty(for age field).

Here I cannot use MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL) since I need to process null values for required=false fields.

Please let me know how this could be achieved using ObjectMapper.readValue method or any other method that holds good here.

Any suggestions would be appreciated.

You can't use @JsonProperty for null validation. It only checks whether value is present or not. From javadocs

Property that indicates whether a value (which may be explicit null) is expected for property during deserialization or not.

For null validation you can use Bean validation JSR-380. Hibernate example:

Maven dependencies:

<!-- 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>

Then you can use it like:

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM