জ্যাকসন ব্যবহার করে জেএসওনকে অ্যারেলিস্ট <পিওজো>> এ ডিসিজায়াল করুন


100

আমার একটি জাভা ক্লাস রয়েছে MyPojoযা আমি জেএসএন থেকে ডিসিরিয়ালাইজেশন করতে আগ্রহী। Deserialization MyPojoDeMixInসম্পর্কে আমাকে সহায়তা করার জন্য, আমি একটি বিশেষ মিশ্রণ শ্রেণি কনফিগার করেছি । সঠিক getters এবং setters সঙ্গে মিলিত 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?


উত্তর:


153

আপনি 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- কীভাবে এটি করব তা আমি পাই না ... জেনেরিকগুলি কীভাবে ব্যবহার করতে হয় তার নির্দেশাবলীর জন্য দয়া করে উপরে আমার সম্পাদনা দেখুন see
tacos_tacos_tacos

ভাল, এটি সম্পর্কিত। তবে এটি প্রোডাকশনে ওয়ার্কিং কোড থেকে স্নিপেট et আপনার মিশ্রণটি ভুলে যান, আমি যে কোডটি দেখিয়েছি তা ব্যবহার করুন (তবে অবশ্যই আপনার আসল বিন শ্রেণীর নাম দিয়ে POJO প্রতিস্থাপন করুন)।
অনুমান

আপনার কোডটি সংকলিত হয়েছে, তবে এ arrayList.toString()সম্পর্কে প্রিন্ট করার চেষ্টা করার সময় আমি একটি রান সময় ব্যতিক্রম পাই NullPointerException। আমি অনুমান করছি যে এটি হতে পারে কারণ POJOএটির বৈশিষ্ট্যগুলির জন্য আমার সঠিক নামকরণের কনভেনশনের সাথে আমি সম্মতি রাখছি না, অর্থাৎ পুরো বিষয়টি হ'ল ওয়েব পরিষেবাটি ফিরে আসে Prop1Memberএবং আমার অবজেক্টটি Prop1। এটি শুরু করার জন্য আমি মিশ্রণগুলি ব্যবহার করছি এমন একমাত্র আসল কারণ, সুতরাং @JsonPropertyআমার খাঁটি অবজেক্টগুলির জন্য আমাকে ঘোষণার দরকার নেই ।
টাকোস_ট্যাকোস_টাকোস 22:19 '

4
আপনি কমপক্ষে কোনও তালিকা ফিরে পেয়েছেন তা নিশ্চিত করতে আপনার অ্যারেটি দৃশ্যত পরিদর্শন করুন। এবং যদি প্রয়োজন হয় তবে মিক্সিনটি ফিরে যুক্ত করুন, যা সবকিছুকে ঝরঝরে deserialized করার জন্য টাইপরেফারেন্সের সাথে কাজ করা উচিত
অনুধাবন

4
@ জসনপ্রপার্টি যতটা খারাপ তা লোকেদের বানায় না। ক্ষেত্রের বর্তমান মানকতার (ন্যূনতম) বর্তমান অবস্থার সাথে কী কী বিক্রেতার নির্দিষ্ট নির্দিষ্ট টিকাদান থেকে দূরে পাওয়া শক্ত।
ধারণা

111

আরেকটি উপায় হ'ল একটি অ্যারেটিকে ধরণ হিসাবে ব্যবহার করা, যেমন:

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

আপনি টাইপ অবজেক্টটি সহ সমস্ত ঝামেলা এড়ান এবং আপনার যদি সত্যিই কোনও তালিকার প্রয়োজন হয় তবে আপনি সর্বদা অ্যারেটিকে একটি তালিকায় রূপান্তর করতে পারবেন:

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

আইএমএইচও এটি আরও পাঠযোগ্য।

এবং এটিকে একটি আসল তালিকাতে পরিণত করতে (যা পরিবর্তিত হতে পারে, এর সীমাবদ্ধতাগুলি দেখুন Arrays.asList()) তারপরে কেবল নিম্নলিখিতটি করুন:

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

4
মার্জিত নিশ্চিত, তবে আমি মাইপোজো []। ক্লাসের কারণে এটি উদার করতে অক্ষম, যা আমি প্যারামিটার হিসাবে পাস করতে চাই না।
অ্যাড্রিয়ান রেডগার্স

আমি মনে করি TypeFactoryযে পরবর্তী উত্তরে বর্ণিত হিসাবে ব্যবহার করা হয়েছে: স্ট্যাকওভারফ্লো.com / a / 42458104 / 91497 প্রকারটি নির্দিষ্ট করার জন্য জ্যাকসন উপায়।
জিমিণী

36

এই রূপটি আরও সহজ এবং মার্জিত দেখায়।

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

সুস্পষ্ট CollectionTypeরেফারেন্সের জন্য ধন্যবাদ ।
এরউইন ওয়েসেলস

3

আমিও একই সমস্যাটিতে ভুগছি। আমার একটি জেসন রয়েছে যা অ্যারেলিস্টে রূপান্তরিত হবে।

অ্যাকাউন্টটি দেখতে এমন দেখাচ্ছে।

Account{
  Person p ;
  Related r ;

}

Person{
    String Name ;
    Address a ;
}

উপরের সমস্ত শ্রেণীর যথাযথভাবে মন্তব্য করা হয়েছে। আমি টাইপ রেফারেন্স> () {tried চেষ্টা করেছি তবে কাজ করছে না।

এটি আমাকে অ্যারেলিস্ট দেয় তবে অ্যারেলিস্টে একটি লিঙ্কযুক্ত হ্যাশম্যাপ রয়েছে যা চূড়ান্ত মানগুলি সহ আরও কিছু লিঙ্কযুক্ত হ্যাশম্যাপ ধারণ করে।

আমার কোড অনুসরণ হিসাবে:

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

আমি অবশেষে সমস্যাটি সমাধান করেছি। আমি জসন স্ট্রিংয়ের তালিকাটি সরাসরি অ্যারেলিস্টে রূপান্তর করতে সক্ষম হলাম:

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.
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.