1. 概述

在实际开发中,我们的服务经常需要调用其他 REST 接口来获取数据。Spring 提供了 RestTemplate 来发送同步 HTTP 请求,而返回的数据通常是 JSON 格式,RestTemplate 可以帮我们自动完成反序列化。

本文将介绍三种将 JSON 数组映射为 Java 集合的方式:

  • Object[] 数组
  • 自定义 POJO 数组
  • 使用 ParameterizedTypeReference 映射为 List

2. 示例 JSON、POJO 和服务结构

假设我们有一个接口地址:http://localhost:8080/users,它返回如下 JSON 数据:

[{
  "id": 1,
  "name": "user1"
}, {
  "id": 2,
  "name": "user2"
}]

对应的 Java 实体类如下:

public class User {
    private int id;
    private String name;

    // getters and setters...
}

我们创建一个服务实现类 UserConsumerServiceImpl,依赖注入 RestTemplate

public class UserConsumerServiceImpl implements UserConsumerService {

    private final RestTemplate restTemplate;

    public UserConsumerServiceImpl(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    ...
}

3. 将 JSON 数组映射为 Java 集合的不同方式

当 REST 接口返回的是 JSON 数组时,我们可以采用以下几种方式将其转换为 Java 集合对象。

3.1. 使用 Object[] 接收响应

首先,使用 getForEntity 方法并指定响应类型为 Object[].class

ResponseEntity<Object[]> responseEntity =
   restTemplate.getForEntity(BASE_URL, Object[].class);

然后从响应中提取 body:

Object[] objects = responseEntity.getBody();

此时每个元素都是 LinkedHashMap 类型(Jackson 默认行为),我们需要借助 ObjectMapper 转换为目标类型:

ObjectMapper mapper = new ObjectMapper();

接着进行类型转换和处理:

return Arrays.stream(objects)
  .map(object -> mapper.convertValue(object, User.class))
  .map(User::getName)
  .collect(Collectors.toList());

✅ 优点:通用性强,可以接收任意结构的 JSON 数组
❌ 缺点:效率低,需要额外转换步骤;类型不明确,容易出错

⚠️ 注意:这种方式实际上是 Jackson 在不知道目标类型的情况下,将 JSON 映射成了 LinkedHashMap,后续再手动转换会带来性能开销。

3.2. 使用 User[] 接收响应

更推荐的做法是直接声明目标数组类型为 User[]

ResponseEntity<User[]> responseEntity = 
  restTemplate.getForEntity(BASE_URL, User[].class); 
User[] userArray = responseEntity.getBody();
return Arrays.stream(userArray) 
  .map(User::getName) 
  .collect(Collectors.toList());

✅ 优点:类型安全,避免手动转换
❌ 缺点:仍需转为 List 才能方便操作

这种方式省去了 convertValue 的步骤,提高了代码可读性和执行效率。

3.3. 使用 ParameterizedTypeReference 映射为 List

如果我们希望直接拿到 List<User> 类型,而不是数组,就需要使用 exchange 方法配合 ParameterizedTypeReference

ResponseEntity<List<User>> responseEntity = 
  restTemplate.exchange(
    BASE_URL,
    HttpMethod.GET,
    null,
    new ParameterizedTypeReference<List<User>>() {}
  );
List<User> users = responseEntity.getBody();
return users.stream()
  .map(User::getName)
  .collect(Collectors.toList());

✅ 优点:直接拿到 List,无需转换,类型清晰
❌ 缺点:语法略复杂

⚠️ 注意:由于 Java 泛型存在类型擦除问题,不能直接使用 List<User>.classParameterizedTypeReference 利用了匿名内部类保留泛型信息的特性,从而绕过这一限制。

4. 总结

方式 类型 是否推荐 说明
Object[] 通用但需手动转换 效率低,仅适合简单场景
User[] 类型安全,但仍是数组 简单粗暴,适合大多数情况
ParameterizedTypeReference<List<User>> 泛型 List,类型明确 ✅✅ 更符合 Java 集合习惯,推荐用于正式项目

📌 建议

  • 如果只是临时读取或统计数量,可以用 Object[]
  • 如果要对数据进一步处理,优先考虑 User[]List<User>
  • 正式项目中建议统一使用 ParameterizedTypeReference + exchange,保证类型安全和代码一致性

完整示例代码见 GitHub:https://github.com/eugenp/tutorials/tree/master/spring-web-modules/spring-resttemplate-2


原始标题:Get list of JSON objects with Spring RestTemplate | Baeldung