首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >当属性不存在时,强制Jackson/Gson在反序列化过程中抛出异常

当属性不存在时,强制Jackson/Gson在反序列化过程中抛出异常
EN

Stack Overflow用户
提问于 2018-06-05 05:13:59
回答 2查看 465关注 0票数 0

我有JSON

{"name": "testname"}

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

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

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

示例jackson:

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

回答 2

Stack Overflow用户

发布于 2018-06-05 05:23:24

使用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;
    }
}

编辑I

我知道你想要的正好相反:)

我不认为gson本身就支持这一点,但我发现这个答案可以满足您的需求:Java to Json validation using 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();
}            
票数 0
EN

Stack Overflow用户

发布于 2018-06-05 05:50:44

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

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,并尝试首先验证它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50688866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档