【问题标题】:Force Jackson/Gson during deserialization to throw exception when property does't exists在反序列化期间强制 Jackson/Gson 在属性不存在时抛出异常
【发布时间】:2018-06-04 21:13:58
【问题描述】:

我有JSON:

{"name": "testname"}

还有拥有数千个属性的 java 类:

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

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

杰克逊示例:

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

【问题讨论】:

    标签: java jackson gson json-deserialization jackson2


    【解决方案1】:

    您必须创建一个需要所有必需属性的构造函数:

    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)
    

    也看看这个问题和答案:Jackson @JsonProperty(required=true) doesn't throw an exception

    编辑
    如果您有数千个属性(这很奇怪但可能),简单的解决方案是将JSON 反序列化为Map 并检查它的大小。如果大小与预期不同,您可以抛出新异常或返回 null

    我认为最好的方法是为您的JSON 生成JSON Schema 并尝试先验证它。

    【讨论】:

    • 没有构造函数的UI类
    • @elronsmith,如果您无法创建构造函数,则必须手动编写检查或创建 JSON Schema
    【解决方案2】:

    使用 gson 没有问题,它只会设置 name 的值。

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

    【讨论】:

    • 如果json没有title参数,Gson应该返回null给Ui。该怎么做?
    猜你喜欢
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 2019-08-08
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多