Spring HATEOS分页响应last链接显示异常求助
问题描述
我正在尝试构建自定义响应对象,但最终响应中的last元素链接不正确。请求地址:/searchx?page=2&size=5&total_required=true,返回的响应中last链接与self链接一致,具体响应如下:
"_links": { "first": { "href": "http://localhost:8080/v1/xx/fxy/x1/searchx?total_required=true&page=0&size=5" }, "prev": { "href": "http://localhost:8080/v1/xx/fxy/x1/searchx?total_required=true&page=1&size=5" }, "self": { "href": "http://localhost:8080/v1/xx/fxy/x1/searchx?total_required=true&page=2&size=5" }, "last": { "href": "http://localhost:8080/v1/xx/fxy/x1/searchx?total_required=true&page=2&size=5" } },
对应的Page资源装配器代码:
Page<MyData> pageRs = new PageImpl<>(data, pageable, total); response.setData(pageRs.getContent()); PagedModel<MyModel> responseModels = pagedResourcesAssembler.toModel(pageRs, datAssembler); response.setLinks(responseModels.getLinks());
解决方案
1. 校验total参数的准确性
PageImpl会根据传入的total值计算最后一页页码,如果total小于等于当前页的起始数据位置(pageable.getPageNumber() * pageable.getPageSize()),就会判定当前页为最后一页,导致last链接与self一致。
- 确认
total是实际的总数据条数,比如当前请求page=2&size=5,若总数据是12条,最后一页应为page=1,如果total误传为15,就会出现last链接错误。
2. 检查pageable参数的正确性
确认pageable对象中的pageNumber和pageSize与请求参数完全一致,避免分页参数在传递过程中被篡改。
3. 手动修正last链接(兜底方案)
如果上述排查后问题仍存在,可以手动计算最后一页页码并替换错误的last链接:
Page<MyData> pageRs = new PageImpl<>(data, pageable, total); response.setData(pageRs.getContent()); PagedModel<MyModel> responseModels = pagedResourcesAssembler.toModel(pageRs, datAssembler); // 计算正确的最后一页页码(页码从0开始) int lastPage = total > 0 ? (int) Math.ceil((double) total / pageable.getPageSize()) - 1 : 0; // 替换last链接 if (lastPage != pageable.getPageNumber()) { Link originalLastLink = responseModels.getRequiredLink(IanaLinkRelations.LAST); UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(originalLastLink.getHref()); uriBuilder.replaceQueryParam("page", lastPage); Link correctedLastLink = Link.of(uriBuilder.toUriString(), IanaLinkRelations.LAST); // 更新links列表 List<Link> updatedLinks = responseModels.getLinks().stream() .map(link -> link.getRel().equals(IanaLinkRelations.LAST) ? correctedLastLink : link) .collect(Collectors.toList()); response.setLinks(updatedLinks); } else { response.setLinks(responseModels.getLinks()); }
内容的提问来源于stack exchange,提问作者ERK
相关产品推荐
相关产品推荐

