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

能否不使用ParameterizedTypeReference通过Spring RestTemplate获取JSON对象列表?

Spring Boot 3.1.1(基于Spring Framework 6)RestTemplate集合查询解决方案

问题背景

使用RestTemplate时,单个对象查询可通过getForObject直接获取响应体正常运行,但尝试用getForObject获取Collection<Ciencia>集合时,会因泛型类型擦除,导致Jackson将JSON数组反序列化为LinkedHashMap列表,进而抛出ClassCastException异常。

标准可行用法(使用ParameterizedTypeReference)

原本通过exchange方法配合ParameterizedTypeReference的写法可以正确获取泛型集合:

public ResponseEntity<Ciencia> findById(Integer id) {
    return restTemplate.getForEntity("/ciencias/uri/v1/ciencias/{id}",
                                     Ciencia.class,
                                     id);
}

public ResponseEntity<Collection<Ciencia>> findAll() {
    return restTemplate.exchange("/ciencias/uri/v1/ciencias",
                                 HttpMethod.GET,
                                 null,
                                 new ParameterizedTypeReference<Collection<Ciencia>>() {});
}

说明

  • 两者均返回ResponseEntity<T>类型,可获取请求头、状态码及响应体。

单个对象直接获取响应体的写法也可正常运行:

public Ciencia findById(Integer id) {
    return restTemplate.getForObject("/ciencias/uri/v1/ciencias/{id}",
                                     Ciencia.class,
                                     id);
}

无需ParameterizedTypeReference的解决方案

1. 数组接收后转集合

利用数组的具体类型信息,避免泛型类型擦除问题:

public Collection<Ciencia> findAll() {
    Ciencia[] cienciasArray = restTemplate.getForObject("/ciencias/uri/v1/ciencias", Ciencia[].class);
    // 如需可变集合,可替换为 new ArrayList<>(Arrays.asList(cienciasArray))
    return Arrays.asList(cienciasArray);
}

原理:数组的类型是明确的Ciencia[],不存在泛型擦除,Jackson能直接将JSON元素反序列化为Ciencia对象,不会转为LinkedHashMap。

2. 自定义泛型响应包装类

如果后端接口返回的是包含集合的对象(而非直接返回数组),可定义包装类来承载响应:

// 泛型响应包装类
public class ListResponse<T> {
    private List<T> items;

    // getter 和 setter
    public List<T> getItems() {
        return items;
    }

    public void setItems(List<T> items) {
        this.items = items;
    }
}

// RestTemplate 查询方法
public Collection<Ciencia> findAll() {
    ListResponse<Ciencia> response = restTemplate.getForObject("/ciencias/uri/v1/ciencias", ListResponse.class);
    return response.getItems();
}

注意:此方式要求接口返回的JSON结构与包装类匹配,例如{"items": [/* Ciencia实例列表 */]}。

关于Spring Framework 5.x的说明

Spring Framework 5.x并未针对RestTemplate新增直接获取泛型集合的特殊方法,泛型类型擦除的限制依然存在,上述两种解决方案在Spring 5.x及6.x版本中均适用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 17:16:10