2016-04-14 122 views
0

Json'u polimorfik sınıflara serpiştirmenin basit bir örneğini yapmaya çalışıyorum. Sadece bu sınıf için JSON kullanarak tek alt sınıf için deserialization çalışırsanızJackson Dizi Olmayan Polimorfik Sınıfları Deserialize Edin

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

, Başarılı, ama SubClassTestObject içinde birlikte iki sınıf koyduğumuzda, başarısız: seri kaldırma hatası ile başarısız olur. Bunu düzeltmek için bir fikrin var mı? Özel bir desperizer yazmam gerekiyor mu? İşte

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

benim sınıfları şunlardır: Burada

benim JSON olduğunu Düzenlemenizle sonra

@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

Sorunun güncellenmesi ... – PunDefeated

+0

Gelecekte, lütfen gönderilmeden önce lütfen sorunuzu gözden geçirin. Bu çok farklı bir senaryo. – Savior

+0

Kötü, ilk cevabı gördükten sonra sorunlardan birinin ne olduğunu gördüm, düzeltdim ve başka bir konuya dönüştü. – PunDefeated

cevap

1

:

Bu burada

@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; 
    } 
} 

Ve benim sınavım

@JsonProperty("classA") 
SubClassA a; 

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

JsonTypeInfo.As.WRAPPER_OBJECT tamamen ilgisiz olan örtülü olması kastedilmektedir. POJO'larınızda bir harita değil. Mevcut JSON'unuzu bu strateji ile eşleyemezsiniz. Örneğin, JsonTypeInfo'unüzü aşağıdaki gibi yapın ya da JsonTypeInfo.As.PROPERTY'u kullanın, ardından ilgili @type (ve uygun değeri) özelliğini JSON'da belirtin.


Öncesi düzenleme:

Sizin SubClassTestObject sınıf Bunlar JSON mevcut değildir çünkü

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

iki özelliklerini a ve b sahiptir. Ve Jackson'a bilinmeyen özellikleri görmezden geldiğinden beri, bu, seriden vazgeçmek için başarısız olmaz. Ancak, her ikisi de başlatılmamış bırakılacak.

sen serisini anlamına JSON kök SubClassTestObject nesne için a ve b sahiptir

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

olduğunu. Ve bunlar, sarıcı nesnelerini uygun JsonTypeInfo adıyla kullanır.

+0

Hmm ile basma ek açıklamaları ekleyebilirsiniz. Yine de Json'u aynı tutmalıyım. Sorumu güncelliyorum. – PunDefeated

+0

JSON'u değiştirmeden bu yapılabilir mi? Pratik için bu basit davayı yapıyorum, ama benim projemde şu anda içinde bulunduğu JSON ile uğraşmak zorunda kalacağım. Benim tek seçeneğim gibi görünüyor o zaman SubClassTestObject için özel bir deserializer yazmak olabilir. – PunDefeated

+1

@PunDefeated Geçerli JSON'unuzla, hayır, JsonTypeInfo ile net bir şekilde göremiyorum. – Savior

İlgili konular