Заставить Джексона / Гсона при десериализации генерировать исключение, когда свойство не существует

Я имею JSON:

{"name": "testname"}

И Java-класс с тысячами свойств:

public class Ui {
    public String name;
    public String title;
}

В процессе десериализации Jackson или же Gson должен вернуться null или выбросить исключение, потому что свойство title не существует в данном JSON, Как заставить это поведение?

Пример Джексона:

ObjectMapper objectMapper = new ObjectMapper();
Ui ui = objectMapper.readValue("{\"name": "testname\"}", Ui.class);
System.out.println(ui == null); // should be true

2 ответа

Вы должны создать конструктор, который требует все необходимые свойства:

class Ui {
    private String name;
    private String title;

    @JsonCreator
    public Ui(@JsonProperty(required = true, value = "name") String name, @JsonProperty(required = true, value = "title") String title) {
        this.name = name;
        this.title = title;
    }
//....
}

И тот же пример дает:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Missing required creator property 'title' (index 1)
 at [Source: {"name": "name"}; line: 1, column: 16]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)

Также посмотрите на этот вопрос и ответы: Джексон @JsonProperty(обязательно =true) не выдает исключение

РЕДАКТИРОВАТЬ
Если у вас есть тысячи свойств (что странно, но возможно), простое решение заключается в десериализации JSON в Map и проверьте его размер. Если размер отличается от ожидаемого, вы можете выдать новое исключение или вернуть null,

Лучший способ, я думаю, это будет генерировать JSON Schema для тебя JSON и попробуйте сначала проверить это.

Используя gson, он работает без проблем, он только устанавливает значение для имени.

public class SO_50688866 {

    public static void main(String ... args) {
        String json = "{\"name\": \"testname\"}";

        Ui ui = new Gson().fromJson(json, Ui.class);

        System.out.println(ui.name);
    }

    public static class Ui {
        public String name;
        public String title;
    }
}

РЕДАКТИРОВАТЬ Я

Я вижу, вы хотели с точностью до наоборот:)

Я не вижу, что gson поддерживает это изначально, но я нашел ответ, который мог бы удовлетворить ваши потребности: проверка Java на Json с использованием GSON

Также я придумал этот класс, который может выполнять проверку полей после десериализации строки json. Он имеет несколько предостережений, например, если отсутствует пропущенный примитив, например, int, он будет инициализирован нулем, поэтому он не будет нулевым. Или если эффективно, если поля в JSON равны нулю. Но, возможно, вы можете адаптировать его для своих нужд, например, добавить метод, который берет имена полей для проверки.

public static class CheckNullFields<T>{
        @SuppressWarnings("unchecked")
        public void check(T obj) throws IllegalAccessException{
            Class<T> clazz = (Class<T>) obj.getClass();
            Field [] fields = clazz.getDeclaredFields();
            for(Field field : fields) {
                if(field.get(obj) == null) {
                    throw new RuntimeException("Null value in field " + field.getName());
                }
            }
        }
    }

Вы бы использовали это так:

String json = "{\"name\": \"testname\"}";       
try {
    Ui ui = new Gson().fromJson(json, Ui.class);
    new CheckNullFields<Ui>().check(ui);
    System.out.println(ui.name);
    System.out.println(ui.title);
}catch(Exception e) {
    e.printStackTrace();
}            
Другие вопросы по тегам