2017-06-13 9 views
1

同じJSONプロパティに対して3つの異なる型を返すサードパーティ製のAPIを使用しています。私はこれらのオブジェクトをデシリアライズするための最善の方法をJackson(好ましくはRetrofit)を使用して理解しようとしています。プロパティの複数の型を持つJSONの逆シリアル化

簡略化した例:このAPIから顧客レコードを取得するとき、応答はのいずれかであるかもしれない:

  1. お客様が複数の電話番号を持っています。顧客が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. お客様が何の電話番号を持っていない返します。空の文字列(!)

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

現在返し、私は例えば、Map<String, Object>にジャクソンとデシリアライズし、それが何であるかのタイプを決定するためにObjectを検査し、その後にそれを挿入することによって、これを処理しますList<PhoneObject>(オブジェクトが存在しない場合は空のListを返します)。しかし、これは扱いにくく、これらのオブジェクトを逆シリアル化するためのよりクリーンな方法を探したいと考えています。

+0

正常な応答を返すためにAPIを修正するよう依頼できますか? – SLaks

+0

私はそれが最良の解決策になることに同意します。残念ながら、これはこの場合のオプションではありません。 – Rob

答えて

2

私はこのObjectMapper構成で、このPhonesクラス

class Phones { 
    @JsonProperty("PhoneObject") 
    private List<PhoneObject> phoneObjects; 
} 

にすべての3 JSON文字列を解析することができました:

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として解析することができます。この場合、phoneObjectsnullとなります。理想的ではありませんが、ここで空のリストを取得する簡単な方法はわかりません。

POJOに応じて、UNWRAP_ROOT_VALUEが必要な場合とそうでない場合があります。

+0

ありがとうございます。この作品は魅力的なものばかりでなく、ジャクソンについて多くのことを学びました。 – Rob

関連する問題