2011-07-01 14 views
24

मेरे पास कुछ कक्षाएं ए, बी, सी हैं, वे सभी वर्ग बेस क्लास से प्राप्त हैं।जावा और जैक्सन लाइब्रेरी का उपयोग करके मैं पॉलिमॉर्फिक deserialization जेसन स्ट्रिंग कैसे कर सकते हैं?

मेरे पास एक स्ट्रिंग जेसन है जिसमें ए, बी, सी या बेस क्लास का जेसन प्रतिनिधित्व शामिल है।

मैं बेस स्ट्रैस (पॉलिमॉर्फिक deserialization) में इस स्ट्रिंग को deserialize करने के लिए कुछ रास्ता चाहते हैं। इस

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

jsonString की तरह कुछ ए, बी, सी, या BaseClass में से किसी का JSON स्ट्रिंग प्रतिनिधित्व हो सकता है।

उत्तर

40

यह स्पष्ट है कि समस्या क्या मूल रूप से पोस्ट कर रहा है नहीं है। मेरा अनुमान है कि यह है कि यह दो में से एक है:,

अनबाउंड JSON तत्वों के साथ
  1. Deserialization समस्याओं क्योंकि JSON तत्व है जो के लिए करने के लिए बाध्य करने के लिए जावा में कोई बात नहीं है होता है; या

  2. पॉलिमॉर्फिक deserialization को लागू करना चाहते हैं।

यहां पहली समस्या का समाधान है।

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

दूसरी समस्या का समाधान यहां दिया गया है।

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

अगर इसके बजाय, लक्ष्य एक JSON तत्व विशेष रूप से इंगित करने के लिए क्या उपवर्ग प्रकार है समर्पित बिना एक उपवर्ग प्रकार के deserialize करने के लिए है, तो वह भी संभव है, जब तक कि JSON में कुछ करने के लिए इस्तेमाल किया जा सकता तय करें कि सबक्लास प्रकार क्या होना चाहिए। मैंने http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html पर इस दृष्टिकोण का एक उदाहरण पोस्ट किया।

+2

आप बस स्पॉट मारा। यह दूसरी समस्या है जो मैं संबंधित हूं। धन्यवाद! – mohamede1945

+0

क्षमा करें, मैं पर्याप्त स्पष्ट नहीं था। मैंने अपनी चिंता को दर्शाने के लिए प्रश्न संपादित किया है। – mohamede1945

+0

मैं वास्तव में समस्या # 1 के समाधान की तलाश में था - FAIL_ON_UNKNOWN_PROPERTIES == झूठी बस मुझे जो चाहिए था :) – pedorro

2

क्या आपने Google की Gson लाइब्रेरी को देखा है? मुझे लगता है कि यह वही करता है जो आप खोज रहे हैं।

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

+0

मैंने अभी अपनी परियोजना में जीसन का उपयोग किया है। यह अच्छा और आसान था। – Bohemian

+1

असल में जैक्सन लाइब्रेरी का उपयोग करने की आवश्यकता है। – mohamede1945

+2

जीसन की वर्तमान रिलीज में पॉलिमॉर्फिक deserialization को संभालने के लिए एक अंतर्निहित तंत्र नहीं है। अगली रिलीज ऐसा लगता है कि इसमें यह सुविधा होगी। –

संबंधित मुद्दे