programing

Jackson을 사용하여 JSON을 ArrayList로 역직렬화

sourcetip 2022. 12. 26. 21:56
반응형

Jackson을 사용하여 JSON을 ArrayList로 역직렬화

자바 수업이 있습니다.MyPojoJSON에서 디시리얼라이즈 하는 것에 관심이 있다고 합니다.특별한 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) }

이 문제를 완화할 수 있는 것은 Response 오브젝트뿐입니다.ArrayList<MyPojo>그 안에 있지만, 그 다음에는 내가 되돌리고 싶은 모든 타입에 대해 이런 다소 쓸모없는 오브젝트를 만들어야 할 것이다.

나도 JacksonInFiveMinutes에서 온라인으로 찾아봤지만, 그것에 대한 것들을 이해하는 데 끔찍한 시간을 보냈다.Map<A,B>그게 내 문제와 어떻게 관련이 있는지 말이야모르시겠지만 저는 자바에 전혀 익숙하지 않고 Obj-C 출신입니다.구체적으로 다음과 같은 내용을 언급합니다.

POJO 및 "단순" 유형에 대한 바인딩 외에도 범용(타입) 컨테이너에 대한 바인딩이 있습니다.이 경우 이른바 타입 소거(Java에서 약간 하위 호환성이 있는 방법으로 제네릭스를 구현하기 위해 사용됨) 때문에 특별한 처리가 필요합니다.이 경우 Collection.class(컴파일하지 않음)를 사용할 수 없습니다.

따라서 데이터를 맵에 바인딩하려면 다음을 사용해야 합니다.

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

어떻게 직접 디시리얼라이즈 할 수 있나요?ArrayList?

를 사용하여 목록으로 직접 역직렬화할 수 있습니다.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 자바독

또 다른 방법은 어레이를 유형으로 사용하는 것입니다.예를 들어 다음과 같습니다.

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

이렇게 하면 Type 객체에 대한 번거로움이 없어집니다.또, 정말로 리스트가 필요한 경우는, 다음의 방법으로 어레이를 리스트로 변환할 수 있습니다.

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

IMHO 이게 훨씬 더 읽기 쉬워요.

실제 리스트가 되도록 하려면 (수정 가능한)Arrays.asList())는, 다음의 조작을 클릭합니다.

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

이 변형은 더 심플하고 우아해 보인다.

//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.type.CollectionType;
//import com.fasterxml.jackson.databind.type.TypeFactory;

//import java.util.List;


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

저도 같은 문제를 겪고 있어요.ArrayList로 변환되는 json이 있습니다.

계좌는 다음과 같습니다.

Account{
  Person p ;
  Related r ;

}

Person{
    String Name ;
    Address a ;
}

위의 모든 클래스에 주석이 올바르게 부착되어 있습니다.TypeReference>() {}을(를) 시도했지만 작동하지 않습니다.

ArrayList는 표시되지만 ArrayList에는 최종값을 포함하는 링크된 해시맵이 포함된 linkedHashMap이 있습니다.

코드는 다음과 같습니다.

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

나는 마침내 문제를 해결했다.다음과 같이 Json String의 List를 ArrayList로 직접 변환할 수 있습니다.

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

}

난 이거면 돼.

@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.
}

언급URL : https://stackoverflow.com/questions/9829403/deserialize-json-to-arraylistpojo-using-jackson

반응형