2011-07-01 26 views
24

A, B, C sınıflarım var, hepsi BaseClass sınıfından miras alıyorlar.Java ve Jackson Kütüphanesi'ni kullanarak Json String'i nasıl polimorfik hale getirebilirim?

A, B, C veya BaseClass'ın json gösterimini içeren bir String json'um var.

Bu String'i BaseClass'a (polimorfik serileştirme) serileştirmenin bir yolunu bulmak istiyorum. Bu

BaseClass base = ObjectMapper.readValue(jsonString, BaseClass.class); 

jsonString gibi bir şey, A, B, C ya da BaseClass herhangi birindeki Json dize temsili olabilir.

cevap

40

Orijinal Poster yaşıyor hangi problemi net değil. Ben iki şeyden birini olduğunu tahmin ediyorum: JSON bağlanma Java şey yok olduğu unsurları içerdiğinden, ilişkisiz JSON elemanları ile

  1. Seri kaldırma sorunları; veya polimorfik seri hale getirme işlemini uygulamak ister.

İşte ilk soruna bir çözüm.

import static org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES; 

import org.codehaus.jackson.map.ObjectMapper; 

public class Foo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    BaseClass base = new BaseClass(); 
    A a = new A(); 
    B b = new B(); 
    C c = new C(); 

    ObjectMapper mapper = new ObjectMapper(); 

    String baseJson = mapper.writeValueAsString(base); 
    System.out.println(baseJson); // {"baseName":"base name"} 
    String aJson = mapper.writeValueAsString(a); 
    System.out.println(aJson); // {"baseName":"base name","aName":"a name"} 
    String bJson = mapper.writeValueAsString(b); 
    System.out.println(bJson); // {"baseName":"base name","bName":"b name"} 
    String cJson = mapper.writeValueAsString(c); 
    System.out.println(cJson); // {"baseName":"base name","cName":"c name"} 

    BaseClass baseCopy = mapper.readValue(baseJson, BaseClass.class); 
    System.out.println(baseCopy); // baseName: base name 

    // BaseClass aCopy = mapper.readValue(aJson, BaseClass.class); 
    // throws UnrecognizedPropertyException: 
    // Unrecognized field "aName", not marked as ignorable 
    // because the JSON contains elements for which no Java field 
    // to bind to was provided. 

    // Need to let Jackson know that not all JSON elements must be bound. 
    // To resolve this, the class can be annotated with 
    // @JsonIgnoreProperties(ignoreUnknown=true) or the ObjectMapper can be 
    // directly configured to not FAIL_ON_UNKNOWN_PROPERTIES 
    mapper = new ObjectMapper(); 
    mapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); 

    BaseClass aCopy = mapper.readValue(aJson, BaseClass.class); 
    System.out.println(aCopy); // baseName: base name 
    BaseClass bCopy = mapper.readValue(bJson, BaseClass.class); 
    System.out.println(bCopy); // baseName: base name 
    BaseClass cCopy = mapper.readValue(cJson, BaseClass.class); 
    System.out.println(cCopy); // baseName: base name 
    } 
} 

class BaseClass 
{ 
    public String baseName = "base name"; 
    @Override public String toString() {return "baseName: " + baseName;} 
} 

class A extends BaseClass 
{ 
    public String aName = "a name"; 
    @Override public String toString() {return super.toString() + ", aName: " + aName;} 
} 

class B extends BaseClass 
{ 
    public String bName = "b name"; 
    @Override public String toString() {return super.toString() + ", bName: " + bName;} 
} 

class C extends BaseClass 
{ 
    public String cName = "c name"; 
    @Override public String toString() {return super.toString() + ", cName: " + cName;} 
} 

Burada ikinci soruna bir çözüm var.

import org.codehaus.jackson.annotate.JsonSubTypes; 
import org.codehaus.jackson.annotate.JsonSubTypes.Type; 
import org.codehaus.jackson.annotate.JsonTypeInfo; 
import org.codehaus.jackson.map.ObjectMapper; 

public class Foo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    BaseClass base = new BaseClass(); 
    A a = new A(); 
    B b = new B(); 
    C c = new C(); 

    ObjectMapper mapper = new ObjectMapper(); 

    String baseJson = mapper.writeValueAsString(base); 
    System.out.println(baseJson); // {"type":"BaseClass","baseName":"base name"} 
    String aJson = mapper.writeValueAsString(a); 
    System.out.println(aJson); // {"type":"a","baseName":"base name","aName":"a name"} 
    String bJson = mapper.writeValueAsString(b); 
    System.out.println(bJson); // {"type":"b","baseName":"base name","bName":"b name"} 
    String cJson = mapper.writeValueAsString(c); 
    System.out.println(cJson); // {"type":"c","baseName":"base name","cName":"c name"} 

    BaseClass baseCopy = mapper.readValue(baseJson, BaseClass.class); 
    System.out.println(baseCopy); // baseName: base name 
    BaseClass aCopy = mapper.readValue(aJson, BaseClass.class); 
    System.out.println(aCopy); // baseName: base name, aName: a name 
    BaseClass bCopy = mapper.readValue(bJson, BaseClass.class); 
    System.out.println(bCopy); // baseName: base name, bName: b name 
    BaseClass cCopy = mapper.readValue(cJson, BaseClass.class); 
    System.out.println(cCopy); // baseName: base name, cName: c name 
    } 
} 

@JsonTypeInfo( 
    use = JsonTypeInfo.Id.NAME, 
    include = JsonTypeInfo.As.PROPERTY, 
    property = "type") 
@JsonSubTypes({ 
    @Type(value = A.class, name = "a"), 
    @Type(value = B.class, name = "b"), 
    @Type(value = C.class, name = "c") }) 
class BaseClass 
{ 
    public String baseName = "base name"; 
    @Override public String toString() {return "baseName: " + baseName;} 
} 

class A extends BaseClass 
{ 
    public String aName = "a name"; 
    @Override public String toString() {return super.toString() + ", aName: " + aName;} 
} 

class B extends BaseClass 
{ 
    public String bName = "b name"; 
    @Override public String toString() {return super.toString() + ", bName: " + bName;} 
} 

class C extends BaseClass 
{ 
    public String cName = "c name"; 
    @Override public String toString() {return super.toString() + ", cName: " + cName;} 
} 

, amaç özellikle alt sınıf türü nedir göstermek için adanmış bir JSON elemanı olmadan bir alt sınıf türüne serisini ise yerine verirse, söz konusu de mümkündür kadar uzun JSON bir şey için kullanılabilir olarak Alt sınıf türünün ne olması gerektiğine karar verin. Bu yaklaşıma bir örnek gönderdim http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html.

+2

Sadece noktayı vurdun. İlgilendiğim ikinci sorun. Teşekkür ederim! – mohamede1945

+0

Üzgünüm, yeterince açık değildim. Soruyu endişemi yansıtacak şekilde düzenledim. – mohamede1945

+0

Aslında sorun # 1 için bir çözüm arıyordum - FAIL_ON_UNKNOWN_PROPERTIES == yanlış sadece neye ihtiyacım vardı :) – pedorro

2

Google'ın Gson kitaplığına baktınız mı? Bence aradığın şeyi yapıyor.

http://code.google.com/p/google-gson/

+0

Projemde gson kullandım. İyi ve kolaydı. – Bohemian

+1

Aslında Jackson Kitaplığı'nı kullanmak şarttır. – mohamede1945

+2

Gson'un mevcut sürümünde, polimorfik serileştirmeyi ele almak için yerleşik bir mekanizma yoktur. Bir sonraki sürüm bu özelliğe sahip gibi görünüyor. –

İlgili konular