जैक्सन का उपयोग करके JSON को ArrayList <POJO> के लिए वर्णन करें


100

मेरे पास एक जावा वर्ग है MyPojoजिसे मैं JSON से अलग करने में दिलचस्पी रखता हूं। मैंने एक विशेष MixIn वर्ग को कॉन्फ़िगर किया है MyPojoDeMixIn, ताकि मुझे डीरिएलाइज़ेशन के साथ सहायता करने के लिए।MyPojoकेवल हैint और Stringउदाहरण चर उचित गेटर्स और बसने के साथ संयुक्त है। MyPojoDeMixInकुछ इस तरह दिखता है:

public abstract class MyPojoDeMixIn {
  MyPojoDeMixIn(
      @JsonProperty("JsonName1") int prop1,
      @JsonProperty("JsonName2") int prop2,
      @JsonProperty("JsonName3") String prop3) {}
}

मेरे परीक्षण ग्राहक में मैं निम्नलिखित कार्य करता हूं, लेकिन निश्चित रूप से यह संकलन समय पर काम नहीं करता है क्योंकि वहाँ है JsonMappingException एक प्रकार का बेमेल से संबंधित है।

ObjectMapper m = new ObjectMapper();
m.getDeserializationConfig().addMixInAnnotations(MyPojo.class,MyPojoDeMixIn.class);
try { ArrayList<MyPojo> arrayOfPojo = m.readValue(response, MyPojo.class); }
catch (Exception e) { System.out.println(e) }

मुझे पता है कि मैं एक "रिस्पांस" ऑब्जेक्ट बनाकर इस मुद्दे को कम कर सकता हूं, जिसमें केवल एक ही ArrayList<MyPojo>है, लेकिन फिर मुझे हर एक प्रकार के लिए कुछ बेकार वस्तुओं को बनाना होगा जो मैं वापस लौटना चाहता हूं।

मैंने जैक्सनइनफाइवमाइन्स पर ऑनलाइन भी देखा लेकिन इस बारे में सामान को समझने में एक भयानक समय था Map<A,B>और यह मेरे मुद्दे से कैसे संबंधित है। यदि आप नहीं बता सकते हैं, तो मैं पूरी तरह से जावा में नया हूं और एक ओब्ज-सी पृष्ठभूमि से आता हूं। वे विशेष रूप से उल्लेख करते हैं:

POJOs और "सरल" प्रकारों के लिए बाध्य करने के अलावा, एक अतिरिक्त प्रकार है: जेनेरिक (टाइप किए गए) कंटेनरों के लिए बाध्यकारी। इस मामले में तथाकथित टाइप एरासुरे (जावा द्वारा इस्तेमाल की गई चीज़ों को कुछ हद तक पीछे की ओर संगत तरीके से लागू करने) के कारण विशेष हैंडलिंग की आवश्यकता होती है, जो आपको संग्रह.क्लास (जो संकलन नहीं करता है) जैसी किसी चीज़ का उपयोग करने से रोकता है।

इसलिए यदि आप डेटा को मैप में बांधना चाहते हैं तो आपको उपयोग करने की आवश्यकता होगी:

Map<String,User> result = mapper.readValue(src, new TypeReference<Map<String,User>>() { });

मैं सीधे किस प्रकार इसका वर्णन कर सकता हूं ArrayList?


यह भी देखें stackoverflow.com/questions/7246157/...
Raedwald

जवाबों:


151

आप TypeReferenceरैपर का उपयोग करके सीधे एक सूची में डिसेररलाइज कर सकते हैं । एक उदाहरण विधि:

public static <T> T fromJSON(final TypeReference<T> type,
      final String jsonPacket) {
   T data = null;

   try {
      data = new ObjectMapper().readValue(jsonPacket, type);
   } catch (Exception e) {
      // Handle the problem
   }
   return data;
}

और इस प्रकार उपयोग किया जाता है:

final String json = "";
Set<POJO> properties = fromJSON(new TypeReference<Set<POJO>>() {}, json);

टाइप रेफरेंस जवादोक


आपका उत्तर उनकी जानकारी से संबंधित लगता है कि अंतर्निहित समर्थन का उपयोग कैसे करें TypeReference- मुझे बस यह करने का तरीका नहीं मिलता है ... कृपया जेनेरिक का उपयोग करने के तरीके के बारे में उनके निर्देशों के लिए मेरा संपादन देखें।
tacos_tacos_tacos

खैर, यह संबंधित है। लेकिन यह उत्पादन में काम करने वाले कोड से एक स्निपेट है। अपने मिक्सिन के बारे में भूल जाओ, बस मेरे द्वारा दिखाए गए कोड का उपयोग करें (लेकिन अपने वास्तविक सेम क्लास के नाम के साथ POJO को बदलें)।
धारणा

आपका कोड संकलित किया गया था, लेकिन जब मुझे इसके arrayList.toString()बारे में जानने का प्रयास किया गया तो मुझे एक रन टाइम अपवाद मिला NullPointerException। मैं अनुमान लगा रहा हूं कि यह इसलिए हो सकता है क्योंकि मेरी POJOअपनी संपत्तियों के लिए सही नामकरण सम्मेलनों के अनुरूप नहीं है, अर्थात, संपूर्ण मुद्दा यह है कि वेब सेवा वापस आती है Prop1Memberऔर मेरी वस्तु है Prop1। यह एकमात्र वास्तविक कारण है कि मैं मिश्रणिन का उपयोग शुरू करने के लिए कर रहा हूं, इसलिए मुझे @JsonPropertyअपनी शुद्ध वस्तुओं के लिए घोषणाएं नहीं करनी हैं।
tacos_tacos_tacos

1
यह सुनिश्चित करने के लिए कि आपने कम से कम सूची वापस प्राप्त की है, अपने व्यूअर का निरीक्षण करें। और अगर जरूरत mixin वापस, जो जोड़ने जा चाहिए सब कुछ पाने के लिए TypeReference के साथ काम बड़े करीने से deserialized।
धारणा

2
@JsonProperty उतनी बुराई नहीं है जितना लोग इसे खत्म कर देते हैं। क्षेत्र में मानकीकरण (न्यूनतम) की वर्तमान स्थिति के साथ विक्रेता विशिष्ट एनोटेशन से दूर होना मुश्किल है।
परसेप्शन

108

एक और तरीका है एक सरणी को एक प्रकार के रूप में उपयोग करना, जैसे:

ObjectMapper objectMapper = new ObjectMapper();
MyPojo[] pojos = objectMapper.readValue(json, MyPojo[].class);

इस तरह से आप टाइप ऑब्जेक्ट के साथ सभी परेशानी से बचते हैं, और अगर आपको वास्तव में एक सूची की आवश्यकता है, तो आप हमेशा सरणी को एक सूची में बदल सकते हैं:

List<MyPojo> pojoList = Arrays.asList(pojos);

IMHO यह बहुत अधिक पठनीय है।

और इसे वास्तविक सूची बनाने के लिए (जिसे संशोधित किया जा सकता है, सीमाएँ देखें Arrays.asList()) तो बस निम्नलिखित करें:

List<MyPojo> mcList = new ArrayList<>(Arrays.asList(pojos));

1
सुरुचिपूर्ण यकीन है, लेकिन मैं MyPojo [] वर्ग के कारण इसे उत्पन्न करने में असमर्थ हूं, जो कि मैं एक पैरामीटर के रूप में पारित नहीं करना चाहता हूं।
एड्रियन रेडर्स

मुझे लगता TypeFactoryहै कि अगले उत्तर में वर्णित अनुसार उपयोग करना : stackoverflow.com/a/42458104/91497 इस प्रकार को निर्दिष्ट करने के लिए जैक्सन तरीका है।
Jmini

35

यह संस्करण अधिक सरल और सुरुचिपूर्ण दिखता है।

CollectionType typeReference =
    TypeFactory.defaultInstance().constructCollectionType(List.class, Dto.class);
List<Dto> resultDto = objectMapper.readValue(content, typeReference);

3

मुझे ठीक यही समस्या है। मेरे पास एक जसन है जिसे ArrayList में बदलना है।

खाता इस तरह दिखता है।

Account{
  Person p ;
  Related r ;

}

Person{
    String Name ;
    Address a ;
}

उपरोक्त सभी वर्गों को ठीक से एनोटेट किया गया है। मैंने TypeReference> () {} की कोशिश की है, लेकिन काम नहीं कर रहा है।

यह मुझे Arraylist देता है लेकिन ArrayList में एक लिंक्डैश है जिसमें अंतिम मूल्यों वाले कुछ और जुड़े हुए हैशमैप हैं।

मेरा कोड इस प्रकार है:

public T unmarshal(String responseXML,String c)
{
    ObjectMapper mapper = new ObjectMapper();

    AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();

    mapper.getDeserializationConfig().withAnnotationIntrospector(introspector);

    mapper.getSerializationConfig().withAnnotationIntrospector(introspector);
    try
    {
      this.targetclass = (T) mapper.readValue(responseXML,  new TypeReference<ArrayList<T>>() {});
    }
    catch (JsonParseException e)
    {
      e.printStackTrace();
    }
    catch (JsonMappingException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

    return this.targetclass;
}

मैंने आखिरकार समस्या हल कर दी। मैं सीधे ArrayList में Json स्ट्रिंग में सूची को परिवर्तित करने में सक्षम हूं:

JsonMarshallerUnmarshaller<T>{

     T targetClass ;

     public ArrayList<T> unmarshal(String jsonString)
     {
        ObjectMapper mapper = new ObjectMapper();

        AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();

        mapper.getDeserializationConfig().withAnnotationIntrospector(introspector);

        mapper.getSerializationConfig().withAnnotationIntrospector(introspector);
        JavaType type = mapper.getTypeFactory().
                    constructCollectionType(ArrayList.class, targetclass.getClass()) ;
        try
        {
        Class c1 = this.targetclass.getClass() ;
        Class c2 = this.targetclass1.getClass() ;
            ArrayList<T> temp = (ArrayList<T>) mapper.readValue(jsonString,  type);
        return temp ;
        }
       catch (JsonParseException e)
       {
        e.printStackTrace();
       }
       catch (JsonMappingException e) {
           e.printStackTrace();
       } catch (IOException e) {
          e.printStackTrace();
       }

     return null ;
    }  

}

2

यह मेरे लिए काम करता है।

@Test
public void cloneTest() {
    List<Part> parts = new ArrayList<Part>();
    Part part1 = new Part(1);
    parts.add(part1);
    Part part2 = new Part(2);
    parts.add(part2);
    try {
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = objectMapper.writeValueAsString(parts);

        List<Part> cloneParts = objectMapper.readValue(jsonStr, new TypeReference<ArrayList<Part>>() {});
    } catch (Exception e) {
        //fail("failed.");
        e.printStackTrace();
    }

    //TODO: Assert: compare both list values.
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.