使用 RestTemplate 返回 List 集合的方法

在 Spring 中,使用 RestTemplate 获取 List 类型的结果需要特殊处理,因为 Java 的类型擦除机制使得无法直接获取 List<T> 类型。以下是几种常用方法:

1. 使用 ParameterizedTypeReference(推荐)

java

复制

下载

RestTemplate restTemplate = new RestTemplate();
String url = "http://example.com/api/users";

ResponseEntity<List<User>> response = restTemplate.exchange(
    url,
    HttpMethod.GET,
    null,
    new ParameterizedTypeReference<List<User>>() {}
);

List<User> users = response.getBody();

2. 使用数组接收然后转换

java

复制

下载

User[] userArray = restTemplate.getForObject(
    "http://example.com/api/users",
    User[].class
);

List<User> userList = Arrays.asList(userArray);
// 或者如果需要可变列表
List<User> userList = new ArrayList<>(Arrays.asList(userArray));

3. 使用包装类

如果 API 返回的是包装对象(推荐 API 设计方式):

java

复制

下载

// 假设返回格式:{"data": [user1, user2, ...]}
public class ApiResponse<T> {
    private List<T> data;
    // getters and setters
}

ApiResponse<User> response = restTemplate.getForObject(
    "http://example.com/api/users",
    ApiResponse.class
);

List<User> users = response.getData();

4. 使用 Jackson 的 TypeReference

java

复制

下载

String json = restTemplate.getForObject("http://example.com/api/users", String.class);

ObjectMapper mapper = new ObjectMapper();
List<User> users = mapper.readValue(json, new TypeReference<List<User>>() {});

5. 配置 RestTemplate 的消息转换器

java

复制

下载

@Configuration
public class RestTemplateConfig {
    
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        
        // 添加支持泛型的消息转换器
        List<HttpMessageConverter<?>> converters = new ArrayList<>();
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(new ObjectMapper());
        converters.add(converter);
        
        restTemplate.setMessageConverters(converters);
        return restTemplate;
    }
}

常见问题解决

1. 类型擦除问题

如果直接使用以下方式会报错:

java

复制

下载

// 错误方式 - 由于类型擦除,无法正确反序列化
List<User> users = restTemplate.getForObject(url, List.class);

2. 处理复杂嵌套结构

对于复杂返回结构如 {"code":0, "message":"success", "data":[user1, user2]}

java

复制

下载

public class Result<T> {
    private int code;
    private String message;
    private List<T> data;
    // getters and setters
}

ResponseEntity<Result<User>> response = restTemplate.exchange(
    url,
    HttpMethod.GET,
    null,
    new ParameterizedTypeReference<Result<User>>() {}
);

List<User> users = response.getBody().getData();

性能优化建议

  1. 重用 RestTemplate 实例:它是线程安全的

  2. 配置连接池:使用 HttpComponentsClientHttpRequestFactory

  3. 设置合理超时:避免请求阻塞

  4. 启用GZIP压缩:减少传输数据量

完整示例

java

复制

下载

@RestController
public class UserController {
    
    private final RestTemplate restTemplate;
    
    public UserController(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }
    
    @GetMapping("/remote-users")
    public List<User> getRemoteUsers() {
        String url = "http://user-service/api/users";
        
        ResponseEntity<List<User>> response = restTemplate.exchange(
            url,
            HttpMethod.GET,
            null,
            new ParameterizedTypeReference<List<User>>() {}
        );
        
        return response.getBody();
    }
}

以上方法中,使用 ParameterizedTypeReference 是最推荐的方式,它能完美解决 Java 泛型类型擦除问题,并且代码清晰易读。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐