java - 使用 Spring RestTemplate 使用分页 API
问题描述
我想使用分页 API。API 由使用 SpringBoot 创建的端点提供。在寻找解决方案时,我在 StackOverflow 上找到了这篇文章。
几乎每个答案都建议创建一个 POJO 来解析。但是由于这是一个标准问题,所以应该有一个框架支持的标准解决方案。在提到的帖子中,Vladimir Mitev给出了答案。他建议使用ParameterizedTypeReference<PagedResources<T>>
. 为了我的目的,我把他的剪掉并改变了类型T
:
restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity, new ParameterizedTypeReference<PagedResources<String>>() {});
这适用于获取页面的内容。但这里的问题是,提供的元数据一直是 null。因此我无法遍历页面,因为我没有得到关于totalPages
. 我是否正确定义了 ResponseType?调试使我发现调用了 PagedResources 的默认构造函数,因此PageMetadata
永远不会设置 Object。
在下文中,我描述了我是如何解决这个问题的。也许它可以帮助其他面临同样问题的人
使用分页 API 的简单方法是:
restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity, String.class);
这让我们对底层数据结构有了一个概念,看起来像这样。
<200,
{
"content":[
"Data1",
"Data2",
"Data3"
],
"pageable":{
"sort":{
"sorted":false,
"unsorted":true,
"empty":true
},
"offset":0,
"pageSize":20,
"pageNumber":0,
"paged":true,
"unpaged":false
},
"number":0,
"sort":{
"sorted":false,
"unsorted":true,
"empty":true
},
"size":20,
"first":true,
"numberOfElements":20,
"totalPages":5,
"totalElements":90,
"last":false,
"empty":false
},
[
Cache-Control:"no-cache, no-store, max-age=0, must
-revalidate",
Content-Type:"application/json;charset=UTF-8",
Date:"Thu, 20 Jun 2019 17:38:18 GMT",
Expires:"0",
Pragma:"no-cache",
Server:"nginx/1.15.10",
X-Content-Type-Options:"nosniff"
它看起来像一个标准的弹簧分页响应对象。所以应该有一种方法可以直接将这个响应转换为某种预定义的对象。
因此我尝试更改 ResponseType 参数:
Page.class
导致
org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.springframework.data.domain.Page]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of org.springframework.data.domain.Page (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
并PageImpl.class
导致
org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.springframework.data.domain.PageImpl]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of org.springframework.data.domain.PageImpl (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
所以必须有另一个 ResponseType 来解析响应。
解决方案
推荐阅读
- json - Spring Boot API - 从客户端发布完整数据
- android-fragments - 在片段内设置来自 Kotlin 中相机的高质量图片
- grafana - 使用 All 选择的 Grafana + Influxdb 模板化变量不会在链接中作为 All 传递,而是作为逗号分隔的值字符串传递
- batch-file - FOR 令牌批处理命令无法隐藏错误“错误:系统无法找到...”
- vue.js - Vue axios 不会更改标题
- google-apps-script - 如何让应用程序脚本在值的数量可以改变的范围内循环
- perl - 在字符串 eq 和查找中使用未初始化的值 $e2:警告:
- geolocation - 如何使用 AppleScript 告诉我的设备与某个位置的当前距离?
- javascript - 如果展开的菜单行溢出,则滚动菜单
- c# - 枚举可以从可为空的原始类型继承吗?