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

SpringBoot用RestTemplate调用服务时RestResponse泛型data转Dto失败问题

问题原因

Java泛型存在类型擦除机制,你调用postForEntity时传入RestResponse.class作为响应类型,运行时无法获取到RestResponse的泛型参数SomeDto,负责反序列化的Jackson库无法识别data字段的目标类型,只能默认将JSON对象反序列化为LinkedHashMap。

注意:你的RestResponse类需要为所有私有字段提供public的getter、setter方法,否则会导致反序列化失败。

解决方案

方案1:使用ParameterizedTypeReference传递泛型信息(推荐)

Spring提供了ParameterizedTypeReference类用于保留泛型类型信息,配合RestTemplate.exchange方法使用即可正确反序列化:

// 构造带泛型信息的类型引用
ParameterizedTypeReference<RestResponse<SomeDto>> typeRef = new ParameterizedTypeReference<RestResponse<SomeDto>>() {};
// 使用exchange方法发起POST请求
ResponseEntity<RestResponse<SomeDto>> result = new RestTemplate().exchange(
    uri,
    HttpMethod.POST,
    new HttpEntity<>(requestBody),
    typeRef
);
// 此时result.getBody().getData()就是已序列化好的SomeDto对象

方案2:手动转换LinkedHashMap(快速兼容现有代码)

如果不想修改原有调用逻辑,可以拿到结果后用Jackson的ObjectMapper手动转换data字段:

ResponseEntity<RestResponse> result = new RestTemplate().postForEntity(uri, requestBody, RestResponse.class);
RestResponse responseBody = result.getBody();
// 手动转换data字段
ObjectMapper objectMapper = new ObjectMapper();
SomeDto someDto = objectMapper.convertValue(responseBody.getData(), SomeDto.class);

方案3:封装通用RestTemplate工具类(适合多场景复用)

如果项目中大量使用RestResponse作为返回结构,可以封装通用工具类简化调用:

public <T> RestResponse<T> postForRestResponse(String uri, Object requestBody, Class<T> dataClass) {
    ParameterizedTypeReference<RestResponse<T>> typeRef = new ParameterizedTypeReference<RestResponse<T>>() {};
    ResponseEntity<RestResponse<T>> response = restTemplate.exchange(
        uri,
        HttpMethod.POST,
        new HttpEntity<>(requestBody),
        typeRef
    );
    return response.getBody();
}

调用时只需传入data对应的Class即可:

RestResponse<SomeDto> response = restTemplateUtil.postForRestResponse(uri, requestBody, SomeDto.class);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:42:02