How to deserialize polymorphic LinkedList with Jackson JSON and JAVA?

时光毁灭记忆、已成空白 提交于 2020-01-05 04:03:19

问题


I´m having some problems when i try to deserializing a Java class. My classes are :

Abstract Class A {
Long ID
String name 
...
}
Class B extends A{ 
String Type
String Value
}
Class C extends A{
List<A> typedList;
}

And my Serialization/Deseralization Methods:

public String serialize(T object) {
        String returnValue = "";

        try {
            returnValue = mapper.writeValueAsString(object);

        } catch (JsonGenerationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println(returnValue);
        return returnValue;
    }

public List<T> unserialize(String data, Class<?> clazz) {
        List<T> returnValue = new LinkedList<T>();
        //JavaType topMost = mapper.getTypeFactory().constructParametricType(MyWrapper.class, ActualClassRuntime.class); 
        try {

            returnValue = (List<T>) mapper.readValue(data,clazz);
        } catch (JsonParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return returnValue;
    }

The list inside the C class contain B and C elements. Serialization is done without problems but when i tried to deserialize C , Jackson can´t rebuild my typedList correctly. It uses LinkedHashMap instead of LinkedList and don´t use the correct types. Any ideias how to solve this ? Thanks in advance!


回答1:


If you expect to get a List, you must pass a List type: here you are giving type of clazz but expect type of List<T>. This won't work, even if clazz is of type List. So you need to pass proper type. But for List (and Map) types, you further need to specify contents type: and type variable does not do. What works is something like:

List<MyType> list = mapper.readValue(jsonSource, new TypeReference<List<MyType>>() { });

where TypeReference must be used due to Java type erasure.

You can also construct structured types from components dynamically, if they are passed as arguments:

Class<?> elem = ...;
List<?> list = mapper.readValue(jsonSource,
  mapper.getTypeFactory().constructCollectionType(ArrayList.class, elem);

The reason you get LinkedHashMap is just because of missing type information: if JSON Object is encountered, and requested type is java.lang.Object (as would be the case if you just passed type List.class to bind to), this is the type that would be used.



来源:https://stackoverflow.com/questions/9487473/how-to-deserialize-polymorphic-linkedlist-with-jackson-json-and-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!