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

如何在Spring Rest Client中获取Page类型的返回内容

在Spring Rest Client中获取Page类型返回内容的解决方案

结合你给出的PersonController和PersonRepository代码,我来一步步教你怎么在Spring Rest Client中正确获取Page<Person>类型的返回结果:

先理解Spring Page的响应结构

你的Controller返回的Page<Person>在序列化后是一个包含分页元数据的JSON对象,结构大概是这样的:

{
  "content": [{"id": 1, "name": "张三"}, ...],
  "totalElements": 100,
  "totalPages": 10,
  "number": 0,
  "size": 10,
  "first": true,
  "last": false,
  "empty": false
}

所以咱们不能直接用普通的对象接收,得处理这种带分页元数据的结构。


方法1:使用RestTemplate(阻塞式客户端)

RestTemplate是Spring传统的阻塞式HTTP客户端,要获取泛型的Page对象,需要借助ParameterizedTypeReference来明确指定泛型类型:

示例代码

import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

public class PersonClient {
    public static void main(String[] args) {
        RestTemplate restTemplate = new RestTemplate();
        String baseUrl = "http://localhost:8080/persons";

        // 构造分页请求参数(page从0开始计数)
        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(baseUrl)
                .queryParam("page", 0)       // 请求第1页(实际是索引0)
                .queryParam("size", 10)      // 每页10条数据
                .queryParam("sort", "id", "asc"); // 按id升序排序

        // 定义返回类型:用PageImpl(Page接口的默认实现类)来接收
        ParameterizedTypeReference<PageImpl<Person>> pageType = new ParameterizedTypeReference<>() {};

        // 发送GET请求并获取响应
        ResponseEntity<PageImpl<Person>> response = restTemplate.exchange(
                uriBuilder.toUriString(),
                HttpMethod.GET,
                null,
                pageType
        );

        // 提取Page对象
        Page<Person> personPage = response.getBody();
        
        // 现在你可以使用分页数据了
        System.out.println("当前页数据量:" + personPage.getNumberOfElements());
        System.out.println("总数据量:" + personPage.getTotalElements());
        System.out.println("数据列表:" + personPage.getContent());
    }
}

关键说明

  • 为什么用PageImpl?因为Page是接口,Spring序列化Page<Person>时实际用的是PageImpl实现类,所以咱们用它来反序列化是最匹配的。
  • 分页参数(page/size/sort)要和Controller中Pageable的默认参数名保持一致,如果你在Controller里自定义了参数名,要同步调整Client的参数。

方法2:使用WebClient(非阻塞式客户端,Spring 5+推荐)

如果你用的是Spring 5及以上版本,更推荐使用WebClient这种非阻塞式的HTTP客户端,写法类似:

示例代码

import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.web.reactive.function.client.WebClient;

public class PersonWebClient {
    public static void main(String[] args) {
        WebClient webClient = WebClient.create("http://localhost:8080");

        Page<Person> personPage = webClient.get()
                .uri(uriBuilder -> uriBuilder.path("/persons")
                        .queryParam("page", 0)
                        .queryParam("size", 10)
                        .queryParam("sort", "id", "asc")
                        .build())
                .retrieve()
                // 同样用ParameterizedTypeReference指定泛型类型
                .bodyToMono(new ParameterizedTypeReference<PageImpl<Person>>() {})
                .block(); // 阻塞获取结果(非阻塞场景可以用subscribe)

        if (personPage != null) {
            System.out.println("总页数:" + personPage.getTotalPages());
            System.out.println("当前页数据:" + personPage.getContent());
        }
    }
}

注意事项

  • 确保Person类是可序列化/反序列化的:要有无参构造函数,字段要有getter/setter,或者用Lombok的@Data注解简化代码。
  • 如果你的Controller返回的是自定义的分页DTO,那Client这边要对应使用自定义的DTO类来接收,而不是PageImpl。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:40:29