I\'m trying to marshal a list: List
objects via the Spring Rest Template.
I can pass along simple Pojo
objects, but I can\'t fi
In Spring 3.2 there is now support for generic types using the new exchange()
-methods on the RestTemplate
:
ParameterizedTypeReference<List<MyBean>> typeRef = new ParameterizedTypeReference<List<MyBean>>() {};
ResponseEntity<List<MyBean>> response = template.exchange("http://example.com", HttpMethod.GET, null, typeRef);
Works like a charm!
One way to ensure that generic type parameters are included is to actually sub-class List or Map type, such that you have something like:
static class MyStringList extends ArrayList<String> { }
and return instance of that list.
So why does this make a difference? Because generic type information is retained in just a couple of places: method and field declarations, and super type declarations. So whereas "raw" List does NOT include any runtime type information, class definition of "MyStringList" does, through its supertype declarations. Note that assignments to seemingly typed variables do not help: it just creates more compile-time syntactic sugar: real type information is only passed with Class instances (or lib-provided extensions thereof, like JavaType and TypeReference in Jackson's case).
Other than this, you would need to figure out how to pass Jackson either JavaType
or TypeReference
to accompany value.
If I read the docs for MappingJacksonHttpMessageConverter right, you will have to create and register a subclass of MappingJacksonHttpMessageConverter
and override the getJavaType(Class<?>) method:
Returns the Jackson JavaType for the specific class. Default implementation returns TypeFactory.type(java.lang.reflect.Type), but this can be overridden in subclasses, to allow for custom generic collection handling. For instance:
protected JavaType getJavaType(Class<?> clazz) {
if (List.class.isAssignableFrom(clazz)) {
return TypeFactory.collectionType(ArrayList.class, MyBean.class);
} else {
return super.getJavaType(clazz);
}
}