2013-02-27 239 views
12

के साथ जेएसओएन क्रमबद्धता मैं जैक्सन 2.1.4 का उपयोग करके जेएसओएन से एक अपरिवर्तनीय पीओजेओ को क्रमबद्ध करने की कोशिश कर रहा हूं, कस्टम सीरिएलाइज़र लिखने के बिना और जितना संभव हो उतना एनोटेशन के साथ। मैं जैक्सन लाइब्रेरी को संतुष्ट करने के लिए अनावश्यक गेटर्स या डिफॉल्ट कन्स्ट्रक्टर को जोड़ने से बचना भी पसंद करता हूं।इन्सटेबल/पॉलिमॉर्फिक POJO <-> जैक्सन

मैं अब अपवाद पर अटक कर रहा हूँ:

JsonMappingException: नहीं उपयुक्त निर्माता प्रकार के लिए मिला [सरल प्रकार, वर्ग सर्किल]: JSON ऑब्जेक्ट से दृष्टांत नहीं कर सकते हैं (जोड़ें/प्रकार की जानकारी सक्षम करने की आवश्यकता?)

कोड:

public abstract class Shape {} 


public class Circle extends Shape { 
    public final int radius; // Immutable - no getter needed 

    public Circle(int radius) { 
    this.radius = radius; 
    } 
} 


public class Rectangle extends Shape { 
    public final int w; // Immutable - no getter needed 
    public final int h; // Immutable - no getter needed 

    public Rectangle(int w, int h) { 
    this.w = w; 
    this.h = h; 
    } 
} 

परीक्षण कोड:

ObjectMapper mapper = new ObjectMapper(); 
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); // Adds type info 

Shape circle = new Circle(10); 
Shape rectangle = new Rectangle(20, 30); 

String jsonCircle = mapper.writeValueAsString(circle); 
String jsonRectangle = mapper.writeValueAsString(rectangle); 

System.out.println(jsonCircle); // {"@class":"Circle","radius":123} 
System.out.println(jsonRectangle); // {"@class":"Rectangle","w":20,"h":30} 

// Throws: 
// JsonMappingException: No suitable constructor found. 
// Can not instantiate from JSON object (need to add/enable type information?) 
Shape newCircle = mapper.readValue(jsonCircle, Shape.class); 
Shape newRectangle = mapper.readValue(jsonRectangle, Shape.class); 

System.out.println("newCircle = " + newCircle); 
System.out.println("newRectangle = " + newRectangle); 

किसी भी मदद की बहुत सराहना की है, धन्यवाद!

उत्तर

10

आप (एपीआई के अनुसार) कर सकता है @JsonCreator साथ निर्माता और @JsonProperty साथ मापदंडों पर टिप्पणी करें।

public class Circle extends Shape { 
    public final int radius; // Immutable - no getter needed 

    @JsonCreator 
    public Circle(@JsonProperty("radius") int radius) { 
     this.radius = radius; 
    } 
} 

public class Rectangle extends Shape { 
    public final int w; // Immutable - no getter needed 
    public final int h; // Immutable - no getter needed 

    @JsonCreator   
    public Rectangle(@JsonProperty("w") int w, @JsonProperty("h") int h) { 
     this.w = w; 
     this.h = h; 
    } 
} 

संपादित करें: शायद तुम @JsonSubTypes साथ आकार वर्ग टिप्पणी करने के लिए इतना है कि आकार के ठोस उपवर्ग निर्धारित किया जा सकता है।

@JsonSubTypes({@JsonSubTypes.Type(Circle.class), @JsonSubTypes.Type(Rectangle.class)}) 
public abstract class Shape {} 
+1

होनहार देखा, लेकिन अब मैं निम्नलिखित अपवाद के बजाय मिल: {इंटरफ़ेस [email protected]son: JsonMappingException: निर्माता [सर्किल के लिए निर्माता, एनोटेशन का तर्क # 0 .annotation.JsonCreator()}] कोई संपत्ति नाम एनोटेशन नहीं है; उस नाम का होना चाहिए जब एकाधिक-पैरामीटर कन्स्ट्रक्टर निर्माता – hammarback

+0

के रूप में एनोटेट किया गया हो हालांकि @JsonProperty एनोटेशन मौजूद है? – nutlike

+0

हां, आपके उदाहरण में। सभी कन्स्ट्रक्टर तर्कों पर। – hammarback

1

आयत दो पैरामीटर है, और FAQ का कहना है:

सरल प्रकार

deserializing मैं के अलावा अन्य प्रकार में सरल JSON मूल्यों (स्ट्रिंग्स, पूर्णांक/ दशमलव संख्या) deserialize चाहते हैं डिफ़ॉल्ट रूप से समर्थित, क्या मुझे कस्टम deserializer लिखने के लिए की आवश्यकता है?

आवश्यक नहीं है।

  • मिलान प्रकार (स्ट्रिंग, पूर्णांक/डबल) के साथ एकल तर्क निर्माता, या
  • एकल तर्क नाम "valueOf()" के साथ स्थिर विधि, और मिलान: वर्ग में deserialize करने के लिए में से एक है, तो तर्क प्रकार

जैक्सन JSON मान से मिलान करने में तर्क के रूप में इस तरह की विधि का उपयोग करेगा।

मुझे डर है कि आप अपने खुद के deserializer as show in the Jackson documentation लिखने के लिए है हूँ:

ObjectMapper mapper = new ObjectMapper(); 
SimpleModule testModule = 
    new SimpleModule("MyModule", new Version(1, 0, 0, null)) 
     .addDeserializer(MyType.class, new MyTypeDeserializer()); 
mapper.registerModule(testModule); 
3

Genson पुस्तकालय इसकी प्रमुख विशेषताओं में से कुछ अपने सटीक समस्या को संबोधित कर रहे हैं पर एक नज़र डालें: बहुरूपता, एनोटेशन और सबसे महत्वपूर्ण अपरिवर्तनीय POJOs की जरूरत नहीं। सब कुछ 0 एनोटेशन या भारी conf के साथ आपके उदाहरण में काम करता है।

Genson genson = new Genson.Builder().setWithClassMetadata(true) 
          .setWithDebugInfoPropertyNameResolver(true) 
          .create(); 

String jsonCircle = genson.serialize(circle); 
String jsonRectangle = genson.serialize(rectangle); 

System.out.println(jsonCircle); // {"@class":"your.package.Circle","radius":123} 
System.out.println(jsonRectangle); // {"@class":"your.package.Rectangle","w":20,"h":30} 

// Throws nothing :) 
Shape newCircle = genson.deserialize(jsonCircle, Shape.class); 
Shape newRectangle = genson.deserialize(jsonRectangle, Shape.class); 

जेन्सन आपको उपनामों (कक्षाओं के नामों के बजाय उपयोग करने) की क्षमता भी प्रदान करता है।

new Genson.Builder().addAlias("shape", Shape.class) 
       .addAlias("circle", Circle.class) 
       .create(); 
+0

यह एक महान टिप है, धन्यवाद! मैं निश्चित रूप से उसमें देख लूंगा! – hammarback