首页 > 解决方案 > 在反序列化期间强制 Jackson/Gson 在属性不存在时抛出异常

问题描述

我有JSON

{"name": "testname"}

以及具有数千个属性的 java 类:

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

在反序列化过程中Jackson或者Gson应该返回null或抛出异常,因为 title 属性在 given 中不存在JSON。如何强制这种行为?

杰克逊的例子:

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

标签: javajacksongsonjson-deserializationjackson2

解决方案


使用 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 to Json validation using GSON

我还想出了这个类,它可以在反序列化 json 字符串后检查字段。它有一些注意事项,例如如果缺少原语,例如 int,它将被初始化为零,因此它不会为空。或者,如果字段在 json 中为 null,则有效。但也许您可以根据自己的需要对其进行调整,例如添加一个采用字段名称进行检查的方法。

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

推荐阅读