Spring/json:转换类型化集合,如List<MyPojo>

2022-09-01 07:21:15

我正在尝试通过 Spring Rest 模板封送一个列表:对象。List<Pojo>

我可以传递简单的对象,但我找不到任何描述如何发送对象的文档。PojoList<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>>() {});

其中 只需要传递泛型类型定义(在本例中通过 anynomous 内部类):重要的部分是定义要绑定到的类型。TypeReference<Map<String,User>>

这可以在Spring模板中完成吗?我看了一眼代码,它使我没有,但也许我只是不知道一些技巧。


溶液

由于下面有用的答案,最终的解决方案是不发送列表,而是发送一个简单地扩展列表的单个对象,例如: 。Spring可以成功地封送这个对象,它完成的事情与发送一个,尽管它的解决方案不那么干净。我还在春季发布了一个JIRA,供他们解决界面中的这个缺点。class PojoList extends ArrayList<Pojo>List<Pojo>HttpMessageConverter


答案 1

Spring 3.2 中,现在支持使用上的新 -methods 的泛型类型:exchange()RestTemplate

 ParameterizedTypeReference<List<MyBean>> typeRef = new ParameterizedTypeReference<List<MyBean>>() {};
 ResponseEntity<List<MyBean>> response = template.exchange("http://example.com", HttpMethod.GET, null, typeRef);

像魔咒一样工作!


答案 2

确保包含泛型类型参数的一种方法是实际使用子类 List 或 Map 类型,这样您就有了如下内容:

static class MyStringList extends ArrayList<String> { }

并返回该列表的实例。

那么,为什么这会有所作为呢?因为泛型类型信息只保留在几个位置:方法和字段声明以及超类型声明。因此,虽然“原始”列表不包含任何运行时类型信息,但“MyStringList”的类定义通过其超类型声明包含。请注意,对看似类型化的变量的赋值没有帮助:它只是创建了更多的编译时语法糖:实类型信息仅使用Class实例(或其lib提供的扩展,如Jackson的JavaType和TypeReference)传递。

除此之外,你还需要弄清楚如何通过杰克逊或伴随价值。JavaTypeTypeReference