Spring Controller接收泛型请求体时需解决类型擦除问题,推荐封装为具体泛型类(如ApiResponse<T>),替代方案为ParameterizedTypeReference或TypeReference手动解析,避免直接使用@RequestBody List<T>。

Spring Controller 接收泛型请求体(@RequestBody)时,JSON 映射本身没有特殊语法限制,但关键在于类型擦除导致的反序列化失败问题——Jackson 默认无法得知泛型的实际类型(如 List<User> 中的 User),所以必须显式提供类型信息。
使用 ParameterizedTypeReference 解决泛型反序列化
当 Controller 方法需要接收如 List<User>、Result<Order> 这类泛型结构时,不能直接写 @RequestBody List<User>(编译通过但运行时报错或数据为空),而应借助 ParameterizedTypeReference 配合 @RequestBody 的封装方式(如用 HttpEntity 或手动解析):
- 推荐做法:将泛型包装进一个具体类(如
Request<T>),Controller 直接接收该类,Jackson 可通过类定义推断 T 的实际类型 - 替代做法:用
@RequestBody接收String,再用ObjectMapper.readValue(json, new TypeReference<List<User>>() {})手动反序列化 - 不推荐:直接写
@RequestBody List<User>—— 因类型擦除,Jackson 只看到List,无法构造User实例,通常返回空列表或抛出Cannot construct instance
定义泛型包装类(推荐且简洁)
创建一个带泛型字段的 DTO,例如:
public class ApiResponse<T> {private int code;
private String message;
private T data;
// getter/setter
}
Controller 中这样写即可正常映射:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
立即学习“Java免费学习笔记(深入)”;
@PostMapping("/order")public ApiResponse<Order> createOrder(@RequestBody ApiResponse<Order> request) {
Order order = request.getData(); // Jackson 已正确反序列化为 Order
return new ApiResponse<>(200, "success", process(order));
}
处理嵌套泛型(如 Map<String, List<Item>>)
若请求体是复杂泛型结构,仍建议封装为具体类。若必须动态解析,用 TypeReference:
public void handleBatch(@RequestBody String json) throws JsonProcessingException {
Map<String, List<Item>> map = objectMapper.readValue(
json,
new TypeReference<Map<String, List<Item>>>() {}
);
}
注意:Lambda 写法 () -> {} 是为了保留泛型签名,不可省略为匿名内部类以外的形式。
确保 Jackson 配置支持泛型(默认已支持)
Spring Boot 2.6+ 默认使用 Jackson,无需额外配置。但需确认:
- 实体类有无参构造器、字段有 public getter/setter(或启用 Lombok
@Data) - 泛型类型不是纯接口或抽象类(如
List<Serializable>无法实例化) - 避免在泛型中使用未标注
@JsonTypeInfo的多态类型(否则反序列化会失败)

















