在反序列化期间强制Jackson / Gson在财产确实存在时抛出异常

时间:2018-06-04 21:13:59

标签: java jackson gson json-deserialization jackson2

我有JSON

{"name": "testname"}

具有数千个属性的java类:

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

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

示例杰克逊:

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

2 个答案:

答案 0 :(得分:0)

使用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,它将被初始化为零,因此它不会为null。或者如果有效,如果字段在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();
}            

答案 1 :(得分:0)

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

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 Schema生成JSON并尝试先验证它。