Проверка (обязательно = true) набора в JsonProperty при использовании ObjectMapper в Джексоне должна выдавать исключение - PullRequest
0 голосов
/ 27 декабря 2018

Я пытаюсь использовать библиотеку Джексона для десериализации, так как у меня есть сценарий, в котором я должен проверить значения 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 установлено в true для JsonProperty и при десериализации, если это свойство встречает null (для полей id и name в приведенном выше коде), я должен выбросить пользовательский DeserializationException.

А также мне нужно обработать значения null (не должно заканчиваться ошибкой) для полей, где в JsonProperty установлено значение required=false (для поля age).

Здесь я не могу использовать MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL), так как мне нужно обработать null значения для required=false полей.

Пожалуйста, дайте мне знать, как этого можно достичь, используя метод ObjectMapper.readValue или любой другой метод, который здесь работает..

Будем благодарны за любые предложения.

1 Ответ

0 голосов
/ 28 декабря 2018

Вы не можете использовать @JsonProperty для проверки нуля.Он только проверяет, присутствует ли значение или нет.From javadocs

Свойство, которое указывает, ожидается ли значение (которое может быть явным нулевым) для свойства во время десериализации.

Для нулевогоДля проверки вы можете использовать Bean validation 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);
}
...