2016-04-14 6 views
0

jsonを多態性クラスに逆直列化する単純な例を実行しようとしています。私はちょうどそのクラスのJSONを使用して、単一のサブクラスのための直列化復元を試みる場合ジャンクション配列としてではなくポリモーフィッククラスを逆シリアル化する

org.codehaus.jackson.map.JsonMappingException: Could not resolve type id 'aField' into a subtype of [simple type, class ...SubClassA] 

、それは成功しますが、私はSubClassTestObject内で一緒に2つのクラスを置くとき、それは失敗します。直列化復元は、エラーで失敗します。これを修正するための任意のアイデア?カスタムデシリアライザを記述する必要がありますか?ここで

は私のJSONです:ここでは

{ 
    "classA":{ 
     "aField":"A", 
     "baseField":"baseA" 
    }, 
    "classB":{ 
     "baseField":"baseB", 
     "bField":"B" 
    } 
} 

は私のクラスです:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT) 
@JsonSubTypes({ 
    @JsonSubTypes.Type(value = SubClassA.class, name = "classA"), 
    @JsonSubTypes.Type(value = SubClassB.class, name = "classB") 
}) 

@JsonIgnoreProperties(ignoreUnknown = true) 
public abstract class AbstractSimpleClass { 
    String baseField; 

    public String getBaseField() { 
     return baseField; 
    } 

    public void setBaseField(String baseField) { 
     this.baseField = baseField; 
    } 
} 

public class SubClassA extends AbstractSimpleClass { 
    String aField; 

    public String getaField() { 
     return aField; 
    } 

    public void setaField(String aField) { 
     this.aField = aField; 
    } 
} 

public class SubClassB extends AbstractSimpleClass { 
    String bField; 

    public String getbField() { 
     return bField; 
    } 

    public void setbField(String bField) { 
     this.bField = bField; 
    } 

} 
@JsonIgnoreProperties(ignoreUnknown = true) 
public class SubClassTestObject { 
    @JsonProperty("classA") 
    SubClassA a; 

    @JsonProperty("classB") 
    SubClassB b; 

    public SubClassA getA() { 
     return a; 
    } 
    public void setA(SubClassA a) { 
     this.a = a; 
    } 
    public SubClassB getB() { 
     return b; 
    } 
    public void setB(SubClassB b) { 
     this.b = b; 
    } 
} 

そしてここでは、私のテストで:

@Test 
public void testBoth() throws IOException, URISyntaxException { 
    ClassLoader classLoader = getClass().getClassLoader(); 
    json = new String(Files.readAllBytes(Paths.get(classLoader.getResource("test/so-example.json").toURI()))); 
    ObjectMapper mapper = new ObjectMapper(); 
    mapper.registerSubtypes(SubClassA.class, SubClassB.class); 

    SubClassTestObject testObj = mapper.readValue(json, SubClassTestObject.class); //Fails here 
    SubClassA a = testObj.getA(); 
    SubClassB b = testObj.getB(); 

    assertTrue(a.getBaseField().equals("baseA")); 
    assertTrue(b.getBaseField().equals("baseB")); 
    assertTrue(a.getaField().equals("A")); 
    assertTrue(b.getbField().equals("B")); 

} 
+0

質問の更新... – PunDefeated

+0

今後、投稿する前に質問を確認してください。これは非常に異なるシナリオです。 – Savior

+0

私の悪い、最初の答えを見た後、私は問題の1つを見ていたので、私はそれを修正し、別の問題に変わった。 – PunDefeated

答えて

1

あなたの編集後:

この

@JsonProperty("classA") 
SubClassA a; 

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT) 

JsonTypeInfo.As.WRAPPER_OBJECTと完全に無関係である暗黙的であることを意味します。 POJOでマッピングするものではありません。この戦略で現在のJSONをマップすることはできません。下の手順を実行するか、JsonTypeInfoJsonTypeInfo.As.PROPERTYを使用するように変更し、対応する@type(およびその適切な値)プロパティをJSONに入力します。


編集前:

あなたSubClassTestObjectクラスはこれらがあなたのJSONには存在しないため、

public SubClassA getA() { 
    return a; 
} 
public SubClassB getB() { 
    return b; 
} 

の二つの性質、abを、持っています。そしてあなたは未知の特性を無視するようにジャクソンに話したので、脱直列化に失敗しません。ただし、両方とも未初期化のままになります。

あなたがデシリアライズするためのものJSONはあなたのルートSubClassTestObjectオブジェクトのabを持って

{ 
    "a": { 
     "classA": { 
      "aField": "A", 
      "baseField": "baseA" 
     } 
    }, 
    "b": { 
     "classB": { 
      "baseField": "baseB", 
      "bField": "B" 
     } 
    } 
} 

です。そして、適切なJsonTypeInfo名前のラッパーオブジェクトを使用します。

+0

とsupressing注釈を追加できるようにするオブジェクトのあなたは、大丈夫うーん、欲しいです私は、しかし、同じjsonを保つ必要があります。私は私の質問を更新しています。 – PunDefeated

+0

これはJSONを変更せずに達成可能ですか?私は練習のために、この単純なケースをやってんだけど、私のプロジェクトで、私はそれが現在の書式でJSONに対処する必要があります。私の唯一のオプションは、その後SubClassTestObject用のカスタムデシリアライザを書くことかもしれように見えます。 – PunDefeated

+1

@PunDefeatedあなたの現在のJSONでは、いいえ、私は 'JsonTypeInfo'で明確な方法を見ていません。 – Savior

関連する問題