java jackson deserializer如何处理同一字段上的Boolean和Object [英] How java jackson deserializer handle both Boolean and Object on same field

查看:672
本文介绍了java jackson deserializer如何处理同一字段上的Boolean和Object的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用第三方JSON API,它会返回如下数据:

I'm working with a 3rd party JSON API, it returns data like this:

{details:{...}, ...}

我使用Java Jackson将此JSON字符串反序列化为POJO对象,字段声明为:

I use Java Jackson to deserialize this JSON string into a POJO object, the field declaration is :

@JsonProperty(details)
公开详情getDetails(){...}

详细信息是另一个类。

一切都很好,直到我发现API可能返回这样的数据:

Everything is fine until I found that API may return data like this:

{details:false,...}

如果详细信息为空,则返回 false !杰克逊给了我这个例外:

If details is empty, it returns false!!! And jackson gave me this exception:

com.fasterxml.jackson.databind.JsonMappingException:无法实例化类型的值[simple type,class Details ]来自布尔值;没有single-boolean / Boolean-arg构造函数/工厂方法(通过引用链:... [details])

所以,如何处理这种JSON字符串?如果为空,我只需要将此字段设置为null。

So, how to handle this kind of JSON string? I only need this field to set to null if empty.

推荐答案

来自Jackson的错误消息暗示该库有支持用于静态工厂方法。这可能是一个比自定义反序列化器更简单的解决方案:

The error message from Jackson hints that the library has bulit in support for static factory methods. This is (perhaps) a simpler solution than a custom deserializer:

我创建了这个示例POJO,使用静态工厂方法,注释以便Jackson使用它:

I created this example POJO, with a static factory method, annotated so that Jackson uses it:

public class Details {
    public String name;  // example property

    @JsonCreator
    public static Details factory(Map<String,Object> props) {

        if (props.get("details") instanceof Boolean) return null;

        Details details = new Details();
        Map<String,Object> detailsProps = (Map<String,Object>)props.get("details");
        details.name = (String)detailsProps.get("name");
        return details;
    }
}

测试方法:

public static void main(String[] args)
{
    String fullDetailsJson = "{\"details\": {\"name\":\"My Details\"}} ";
    String emptyDetailsJson = "{\"details\": false} ";
    ObjectMapper mapper = new ObjectMapper();
    try {
        Details details = mapper.readValue(fullDetailsJson, Details.class);
        System.out.println(details.name);
        details = mapper.readValue(emptyDetailsJson, Details.class);
        System.out.println(details);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

结果符合预期:

My Details
null

这篇关于java jackson deserializer如何处理同一字段上的Boolean和Object的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆