Как десериализовать полиморфный LinkedList с помощью Jackson JSON и JAVA? - PullRequest
1 голос
/ 28 февраля 2012

У меня возникают некоторые проблемы, когда я пытаюсь десериализовать класс Java.Мои классы:

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

И мои методы сериализации / десерализации:

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

Список внутри класса C содержит элементы B и C.Сериализация выполняется без проблем, но когда я попытался десериализовать C, Джексон не смог правильно перестроить свой typedList.Он использует LinkedHashMap вместо LinkedList и не использует правильные типы.Любые идеи, как решить это?Заранее спасибо!

1 Ответ

6 голосов
/ 29 февраля 2012

Если вы ожидаете получить список, вы должны передать тип списка: здесь вы указываете тип clazz, но ожидаете тип List<T>.Это не будет работать, даже если clazz имеет тип List.Таким образом, вы должны передать правильный тип.Но для типов List (и Map) вам также необходимо указать тип содержимого: переменная типа не подходит.Это работает примерно так:

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

, где TypeReference необходимо использовать из-за стирания типа Java.

Вы также можете динамически создавать структурированные типы из компонентов, если они передаются в качестве аргументов:

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

Причина, по которой вы получаете LinkedHashMap, заключается просто в отсутствии информации о типе: если встречается JSON Object, и запрашиваемый тип равен java.lang.Object (как в случае, если вы только что передали тип List.class для привязки), это тип, который будет использоваться.

...