我正在尝试通过Spring Rest Template封送列表:List<Pojo>
个对象。
我可以传递简单的Pojo
个对象,但我找不到任何描述如何发送List<Pojo>
个对象的文档。
Spring正在使用Jackson JSON来实现HttpMessageConverter
。杰克逊的文档涵盖了这一点:
除了绑定到POJO和 “简单”类型,有一个 附加变体:绑定到的变体 通用(类型)容器。这个案例 由于需要特殊处理 所谓的类型擦除(由Java使用) 在某种程度上实现泛型 向后兼容的方式),其中 阻止你使用像
Collection<String>.class
(确实如此 不编译)。所以如果你想将数据绑定到
Map<String,User>
您将需要使用:
Map<String,User> result = mapper.readValue(src, new TypeReference<Map<String,User>>() {});
只需要
TypeReference
传递泛型类型定义(通过 在这种情况下任意内部类): 重要的是<Map<String,User>>
定义类型 绑定到。
这可以在Spring模板中完成吗?我瞥了一眼代码,它让我不是,但也许我只是不知道一些技巧。
解决方案
由于下面的有用答案,最终解决方案是不发送List,而是发送一个只扩展List的对象,例如:class PojoList extends ArrayList<Pojo>
。 Spring可以成功封送这个Object,它完成了与发送List<Pojo>
相同的功能,尽管它不是一个简洁的解决方案。我还在春季发布了一个JIRA,以便他们在HttpMessageConverter
界面中解决这个缺点。
答案 0 :(得分:40)
在Spring 3.2中,现在支持使用exchange()
上的新RestTemplate
- 方法的泛型类型:
ParameterizedTypeReference<List<MyBean>> typeRef = new ParameterizedTypeReference<List<MyBean>>() {};
ResponseEntity<List<MyBean>> response = template.exchange("http://example.com", HttpMethod.GET, null, typeRef);
像魅力一样!
答案 1 :(得分:23)
确保包含泛型类型参数的一种方法实际上是子类List或Map类型,这样就可以得到类似的内容:
static class MyStringList extends ArrayList<String> { }
并返回该列表的实例。
那为什么会有所作为呢?因为泛型类型信息仅保留在几个地方:方法和字段声明以及超类型声明。因此,“raw”List不包含任何运行时类型信息,“MyStringList”的类定义通过其超类型声明来实现。 注意,对看似类型化的变量的赋值没有帮助:它只是创建了更多的编译时语法糖:真正的类型信息只传递给类实例(或者lib提供的扩展,如杰克逊的JavaType和TypeReference)。
除此之外,您需要弄清楚如何通过杰克逊JavaType
或TypeReference
陪伴价值。
答案 2 :(得分:10)
如果我阅读docs for MappingJacksonHttpMessageConverter
权限,则必须创建并注册MappingJacksonHttpMessageConverter
的子类并覆盖getJavaType(Class<?>)
方法:
返回Jackson的Java类型 具体课程。默认实施 回报 TypeFactory.type(java.lang.reflect.Type) 但这可以被覆盖 子类,允许自定义 通用集合处理。对于 实例:
protected JavaType getJavaType(Class<?> clazz) {
if (List.class.isAssignableFrom(clazz)) {
return TypeFactory.collectionType(ArrayList.class, MyBean.class);
} else {
return super.getJavaType(clazz);
}
}