You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring RestTemplate使用ParameterizedTypeReference时遭遇Converter异常

解决RestTemplate使用ParameterizedTypeReference时的Converter异常问题

嗨,我来帮你拆解这个问题——你遇到的Converter异常,核心原因是用ParameterizedTypeReference时没踩对两个关键细节:方法使用错误和泛型类型声明不匹配,而直接转String再手动反序列化时绕开了这些坑。

先理清问题本质

服务器返回的是一个标准的分页结构JSON,包含content数据数组和分页元数据。你用postForObject(..., String.class)能正常工作,是因为RestTemplate默认的字符串消息转换器会直接把响应体转成字符串,之后你用ObjectMapper手动指定泛型类型(比如new TypeReference<Page<YourEntity>>() {})时,Jackson能正确解析泛型结构。但换成ParameterizedTypeReference时,就触发了Converter异常,大概率是下面两个原因:


原因1:用错了RestTemplate方法

很多人会犯这个错:postForObject不支持ParameterizedTypeReference!它的第三个参数只接受Class<T>类型,如果你强行传入ParameterizedTypeReference,RestTemplate会无法识别泛型信息,直接抛出类型转换异常。

正确的做法是用exchange方法,它专门支持ParameterizedTypeReference来处理泛型返回值。

原因2:泛型类型声明不准确

如果你的目标类型是Spring Data的Page接口,直接用new ParameterizedTypeReference<Page<YourEntity>>() {}会失败——因为Jackson无法实例化接口,它需要具体的实现类(比如PageImpl)。另外,如果是自定义分页DTO,要确保DTO的字段和服务器返回的JSON完全匹配(大小写、字段名、类型都要对应)。


具体解决方案

方案1:自定义分页DTO(推荐,更灵活)

先创建和服务器响应结构完全匹配的分页DTO:

public class CustomPage<T> {
    private List<T> content;
    private boolean last;
    private int totalPages;
    private long totalElements;
    private int size;
    private int number;
    private boolean first;
    private Object sort;
    private int numberOfElements;

    // 必须添加无参构造、全参构造,以及所有字段的getter/setter
}

再创建对应content里的实体类:

public class YourEntity {
    private int name;
    private int id1;
    private int id2;

    // 无参构造、getter/setter
}

然后用exchange方法结合ParameterizedTypeReference请求:

// 定义泛型类型引用
ParameterizedTypeReference<CustomPage<YourEntity>> pageTypeRef = 
    new ParameterizedTypeReference<CustomPage<YourEntity>>() {};

// 构建请求实体
HttpEntity<YourRequestData> requestEntity = new HttpEntity<>(data);

// 发起请求并获取响应
ResponseEntity<CustomPage<YourEntity>> response = restTemplate.exchange(
    url,
    HttpMethod.POST,
    requestEntity,
    pageTypeRef
);

// 获取结果
CustomPage<YourEntity> resultPage = response.getBody();

方案2:使用Spring Data的PageImpl(适合已有Spring Data依赖的场景)

如果要直接反序列化为Spring Data的Page,需要指定具体实现类PageImpl,并且给Jackson配置Mixin来支持接口反序列化:

// 创建Page接口的Mixin类,告诉Jackson用PageImpl实例化
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
abstract class PageMixin {}

// 配置RestTemplate的ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(Page.class, PageMixin.class);

MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(0, converter);

// 使用PageImpl作为泛型类型
ParameterizedTypeReference<PageImpl<YourEntity>> pageTypeRef = 
    new ParameterizedTypeReference<PageImpl<YourEntity>>() {};

ResponseEntity<PageImpl<YourEntity>> response = restTemplate.exchange(
    url,
    HttpMethod.POST,
    new HttpEntity<>(data),
    pageTypeRef
);

Page<YourEntity> resultPage = response.getBody();

额外排查点

  • 检查RestTemplate的消息转换器:确保MappingJackson2HttpMessageConverter在消息转换器列表的前面,避免被其他转换器(比如字符串转换器)优先处理。
  • 确认实体类字段匹配:比如服务器返回的name是数字类型,你的实体类对应字段也要是int或Integer,不能是String,否则会触发类型转换异常。

内容的提问来源于stack exchange,提问作者user5591691

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:24:11