使用多种类型的属性进行JSON反序列化

5

我是一个协助翻译的助手。涉及到IT技术,您需要翻译一个与第三方API相关的问题。该问题返回同一JSON属性的三种不同类型,这取决于它包含多少个嵌套对象。我正在尝试找出使用Jackson(最好与Retrofit一起使用)反序列化这些对象的最佳方法。

简单的例子:当从该API检索客户记录时,响应可能是以下任何一种:

  1. Customer has multiple phone numbers; returns an array of PhoneObjects

    {
        "Phones": {
            "PhoneObject":[
                {"number":"800 555 6666","type":"Home"},
                {"number":"800 555 4444","type":"Work"}
            ]
        }
    }
    
  2. Customer has one phone number; return a single PhoneObject

    {
        "Phones": {
            "PhoneObject": {"number":"800 555 6666","type":"Home"}
        },
    }
    
  3. Customer has no phone numbers; return an empty string(!)

    {
        "Phones": {
            "PhoneObject":""
        }
    }
    

目前,我通过使用Jackson反序列化为Map<String, Object>并检查Object来确定它的类型,然后将其插入到例如List<PhoneObject>中(如果该对象不存在,则返回一个空列表)。但是这种方法很麻烦,我希望找到一种更简洁的方法来反序列化这些对象。


你能否请他们修复他们的API,以返回一个合理的响应? - SLaks
我同意那将是最好的解决方案。不幸的是,在这种情况下这不是一个选项。 - Rob
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
7
我能够将这3个JSON字符串都解析成Phones类。
class Phones {
    @JsonProperty("PhoneObject")
    private List<PhoneObject> phoneObjects;
}
使用这个 ObjectMapper 配置:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

ACCEPT_SINGLE_VALUE_AS_ARRAY 允许将一个值解析为大小为1的列表。

ACCEPT_EMPTY_STRING_AS_NULL_OBJECT 允许将空字符串解析为null。在这种情况下,phoneObjects 最终成为 null。虽然不是理想的情况,但我不知道有什么简单的方法来获得一个空列表。

根据您的POJO,您可能需要 UNWRAP_ROOT_VALUE 或者不需要。


1
谢谢。这不仅像魔法一样奏效,而且我还学到了更多关于Jackson的知识。 - Rob
如果我使用gsonBuilder解析数据,该如何操作?( Type type = new TypeToken<ArrayList<ProductModel>>() { }.getType();GsonBuilder gsonBuilder = new GsonBuilder();ArrayList<ProductModel> products = gsonBuilder.create().fromJson(response, type); ) - Shikhar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,