2016-09-01 6 views
5

मैंने इस तरह के डीटीओ जावा में लिखा कक्षाएं:JSON सामान्य संग्रह अक्रमांकन

public class AnswersDto { 
    private String uuid; 
    private Set<AnswerDto> answers; 
} 

public class AnswerDto<T> { 
    private String uuid; 
    private AnswerType type; 
    private T value; 
} 

class LocationAnswerDto extends AnswerDto<Location> { 
} 

class JobTitleAnswerDto extends AnswerDto<JobTitle> { 
} 

public enum AnswerType { 
    LOCATION, 
    JOB_TITLE, 
} 

class Location { 
    String text; 
    String placeId; 
} 

class JobTitle { 
    String id; 
    String name; 
} 

अपने प्रोजेक्ट में जैक्सन क्रमबद्धता और JSONs की अक्रमांकन के लिए इस्तेमाल किया पुस्तकालय है।

AnswersDto (विशेष व्याख्या का उपयोग) या AnswerDto (टिप्पणी के रूप में अच्छी तरह से) कक्षाओं को कैसे कॉन्फ़िगर ठीक से, अपने शरीर में AnswersDto साथ अनुरोध deserialize करने के लिए जैसे सक्षम होने के लिए:

{ 
    "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73", 
    "answers": [ 
     { 
      "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73", 
      "type": "LOCATION", 
      "value": { 
       "text": "Dublin", 
       "placeId": "121" 
      } 
     }, 
     { 
      "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73", 
      "type": "JOB_TITLE", 
      "value": { 
       "id": "1", 
       "name": "Developer" 
      } 
     } 
    ] 
} 

दुर्भाग्य से जैक्सन ने की डिफ़ॉल्ट नक्शे मूल्य AnswerDto ऑब्जेक्ट को LinkedHashMap पर ऑब्जेक्ट (Location या JobTitle) क्लास प्रकार के ऑब्जेक्ट के बजाय ऑब्जेक्ट करें। क्या मुझे कस्टम JsonDeserializer<AnswerDto> लिखना चाहिए या @JsonTypeInfo और @JsonSubTypes के उपयोग से कॉन्फ़िगरेशन पर्याप्त हो सकता है? किसी भी अन्य कस्टम विन्यास के बिना

AnswerDto<Location> answerDto = objectMapper.readValue(jsonRequest, new TypeReference<AnswerDto<Location>>() { 
}); 

:

ठीक से

{ 
    "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73", 
    "type": "LOCATION", 
    "value": { 
     "text": "Dublin", 
     "placeId": "121" 
    } 
} 

के रूप में सिर्फ एक AnswerDto साथ अनुरोध deserialize करने के लिए मैं उपयोग कर रहा हूँ।

+0

आप aswer वस्तुओं का संग्रह है, लेकिन आप केवल एक ही जवाब वस्तु को deserialize करना चाहते हैं? AnswersDto उत्तरों = objectMapper.readValue (jsonRequest, new TypeReference () {}) का उपयोग करने के बारे में क्या; – reos

+0

मैं सभी ऑब्जेक्ट्स को 'उत्तर' नोड से '' संग्रह में मैप करना चाहता हूं। जब मैं 'टाइप रेफरेंस ' के साथ 'ऑब्जेक्टमैपर' का उपयोग करता हूं, तो दुर्भाग्यवश 'मूल्य' संपत्ति से संग्रह से प्रत्येक 'उत्तर' से संपत्ति को 'लिंक्ड हैश मैप' में मैप किया जाता है। – Bananan

उत्तर

5

मैं @JsonTypeInfo और @JsonSubTypes जैक्सन के कस्टम एनोटेशन का उपयोग करके समस्या हल कर ली:

public class AnswerDto<T> { 

    private String uuid; 

    private AnswerType type; 

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type") 
    @JsonSubTypes({ 
      @JsonSubTypes.Type(value = Location.class, name = AnswerType.Types.LOCATION), 
      @JsonSubTypes.Type(value = JobTitle.class, name = AnswerType.Types.JOB_TITLE) 
    }) 
    private T value; 
} 
1

मेरा सुझाव संभावित उत्तर मूल्यों के लिए एक अलग इंटरफ़ेस बनाना है और @JsonTypeInfo पर इसका उपयोग करना है। आप type फ़ील्ड AnswerDto, AnswerType enum से भी छोड़ सकते हैं, और अतिरिक्त *AnswerDto कक्षाएं जैकसन आपके लिए प्रकार की जानकारी जोड़ देंगे। इस

public class AnswerDto<T extends AnswerValue> { 
    private String uuid; 
    private T value; 
} 

@JsonTypeInfo(use = Id.CLASS, include = As.PROPERTY) 
interface AnswerValue {} 

class Location implements AnswerValue { /*..*/ } 
class JobTitle implements AnswerValue { /*..*/ } 

परिणामस्वरूप json इच्छा इस

{ 
    "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73", 
    "answers": [ 
    { 
     "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73", 
     "value": { 
     "@class": "com.demo.Location", 
     "text": "Dublin", 
     "placeId": "121" 
     } 
    }, 
    { 
     "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73", 
     "value": { 
     "@class": "com.demo.JobTitle", 
     "id": "1", 
     "name": "Developer" 
     } 
    } 
    ] 
} 

कौन सा

AnswersDto answersDto = objectMapper.readValue(json, AnswersDto.class); 

का उपयोग कर पार्स किया जाएगा की तरह दिखता है जैसा लेकिन इस समाधान केवल मामलों में लागू होता है जब आप json डेटा की एक निर्माता हैं और आपको पिछड़े संगतता के बारे में सोचना नहीं है।

अन्य मामलों में आपको AnswersDto कक्षा के लिए कस्टम desetializer बनाना होगा।

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