Resttemplate не может разобрать массив типа T

У меня проблема с Spring и restTemplate. Я хочу отправить объект (ListResponse), содержащий общий массив. Дефиниция следующая:

public class ListResponse<T> implements Serializable {

private long total;
private int page;
private int pageSize;
private T[] objects;

Я отправляю запрос с помощью restTemplate.getForObject(). В результате я получаю объект типа ListResponse, но массив объектов содержит массив LinkedHashMaps вместо массива с объектами типа T.

Похоже, что restTemplate не может преобразовать элементы массива в их правильный тип.

Как я могу убедиться, что я верну массив объектов типа T?


person Tom    schedule 10.04.2013    source источник


Ответы (3)


У меня была эта проблема сегодня, и вот решение, которое я придумал (на самом деле, это предложил один из моих коллег). Мы используем его с интерфейсом, который возвращает List‹MyDto›.

При вызове RestTemplate не передавайте общий тип.
Определение: public class MyDtoListTemplate extends ListTemplate<MyDto>

Затем позвоните
MyDtoListTemplate template = restTemplate.getForObject("url", MyDtoListTemplate .class, mapOfPathVariables);

Обидно, что вам нужно определить конкретный класс, который расширяет/реализует универсальный тип, но тогда общая информация доступна для десериализатора Джексона.

person Nathan    schedule 08.07.2013

Я помню, что смог десериализовать общие классы с помощью Jackson 2. Мне пришлось добавить MappingJackson2HttpMessageConverter преобразовывает в RestTemplate, прежде чем совершать с ним какие-либо вызовы Http.

RestTemplate template = new RestTemplate();
template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
person nilesh    schedule 14.04.2013

К сожалению, я не знаю простого способа сделать это. Проблема в том, что RestTemplate сообщается, какой тип объекта следует ожидать. Пока все поля в этом объекте имеют соответствующий элемент в json/xml, все работает нормально. В случае дженериков сериализатор не знает, какой класс ожидать, поэтому он просто превращает полученную карту в карту java.

У вас будет та же проблема, если вы попытаетесь получить ForObject для универсального возвращаемого типа.

person Avi    schedule 10.04.2013
comment
Я могу представить, что RestTemplate не умеет разбирать массив. Но вы указываете, что возвращаемый тип вызова должен быть из типа ListResponse‹Feedback›. Указав это, разве он не должен знать, какие типы объектов хранятся в массиве? (Поскольку вы это указали?) В любом случае, что было бы трудным путем? Я хотел бы знать это, чтобы я мог взвесить все за и против. - person Tom; 11.04.2013
comment
Когда вы объявляете ожидаемый тип, вы обычно делаете что-то вроде (если, например, T предполагает класс с именем MyClass) — MyClass.class. Вы не можете сделать то же самое для дженериков, например ListResponse<Feedback>.class. Я не уверен, в чем причина. Я думаю, это потому, что когда вы создаете универсальный класс, вы создаете шаблон для класса, который фактически создается только во время выполнения (когда тип установлен). О том, как это можно сделать — вы можете выполнить десериализацию самостоятельно. Я сделал это один раз, но я не могу найти код, чтобы вставить сюда. Это не должно быть очень сложно. - person Avi; 11.04.2013