2017-06-13 105 views
1

我正在使用第三方API,它为相同的JSON属性返回三种不同类型,具体取决于它包含多少个嵌套对象。我试图找出处理使用Jackson对这些对象进行反序列化的最佳方法(最好使用Retrofit)。对多个类型的属性进行反序列化JSON

简化示例:从这个API检索顾客记录时,响应可能是任何一个:

  1. 客户拥有的多个电话号码;返回PhoneObjects

    { 
        "Phones": { 
         "PhoneObject":[ 
          {"number":"800 555 6666","type":"Home"}, 
          {"number":"800 555 4444","type":"Work"} 
         ] 
        } 
    } 
    
  2. 顾客的阵列有一个电话号码;退货单PhoneObject

    { 
        "Phones": { 
         "PhoneObject": {"number":"800 555 6666","type":"Home"} 
        }, 
    } 
    
  3. 客户没有电话号码;通过与杰克逊反序列化到Map<String, Object>和检查Object,以确定它是什么类型,然后将其插入,例如返回一个空字符串(!)

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

目前,我处理这个一个List<PhoneObject>(如果对象不存在,则返回一个空列表)。然而,这很麻烦,并希望找到一种更简洁的方式来反序列化这些对象。

+0

你可以让他们修复他们的API来返回一个理智的回应吗? – SLaks

+0

我同意这将是最好的解决方案。不幸的是,这不是一种选择。 – Rob

回答

2

我是能够全部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

+0

谢谢。这不仅仅是一种魅力,而且我学到了更多关于杰克逊的知识。 – Rob