如何在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
相关产品推荐
相关产品推荐

