如何在不使用Hateoas/Data-Rest模块的情况下正确序列化Spring Data PageImpl
Spring Boot分页接口实现与响应解析示例
嘿,我来给你梳理下这个Spring Boot分页接口的实现细节和返回响应的逻辑,帮你更清晰地理解它的工作方式~
首先看你的控制器方法实现:
@RequestMapping(method = RequestMethod.GET, value = "/") public ResponseEntity<Page> getUsers(Pageable pageable) { Page<User> users = repository.findAll(pageable); return ResponseEntity.ok(users); }
这段代码的核心逻辑很清晰:
- 用
@RequestMapping指定了GET请求,路径是根路径/ - 参数
Pageable是Spring Data提供的分页参数封装,前端可以通过page(默认0,注意是从0开始的页码)、size(默认20,每页条数)、sort(比如sort=id,desc来指定按id倒序)这些请求参数来控制分页规则 - 调用
repository.findAll(pageable)时,Spring Data的分页仓库会自动帮你拼接分页SQL,从数据库查询出对应页的用户数据 - 最后通过
ResponseEntity.ok(users)返回200成功状态码,以及完整的分页结果对象
你提到的接口返回响应结构大概是这样的(补全了常见字段):
{ "content": [ { "id": 1, "name": "张三" }, { "id": 2, "name": "李四" } ], "pageable": { "sort": { "sorted": false, "unsorted": true }, "offset": 0, "pageNumber": 0, "pageSize": 20, "paged": true, "unpaged": false }, "totalElements": 100, "totalPages": 5, "last": false, "size": 20, "number": 0, "sort": { "sorted": false, "unsorted": true }, "numberOfElements": 20, "first": true, "empty": false }
这里给你拆解下响应里的关键字段:
content:当前页的实际数据列表,就是你查询到的User对象集合pageable:记录了当前请求的分页参数细节,包含页码、每页大小、排序状态等totalElements:数据库中符合条件的总记录数totalPages:计算出来的总页数(总记录数 ÷ 每页条数,向上取整)number:当前页码(记住是从0开始计数的,0代表第一页)size:每页的记录条数first/last:布尔值,标识当前页是否是第一页/最后一页empty:标识当前页是否没有数据
如果觉得默认返回的pageable等字段太冗余,前端不需要这么多信息,你可以自定义一个分页DTO来封装结果,让响应更简洁:
public class PageResponseDTO<T> { private List<T> content; private long totalElements; private int totalPages; private int currentPage; private int pageSize; private boolean first; private boolean last; // 构造方法、getter和setter省略,你可以用Lombok的@Data注解简化 }
然后修改控制器方法,把Spring Data的Page对象转换成自定义的DTO:
@RequestMapping(method = RequestMethod.GET, value = "/") public ResponseEntity<PageResponseDTO<User>> getUsers(Pageable pageable) { Page<User> users = repository.findAll(pageable); PageResponseDTO<User> response = new PageResponseDTO<>(); response.setContent(users.getContent()); response.setTotalElements(users.getTotalElements()); response.setTotalPages(users.getTotalPages()); response.setCurrentPage(users.getNumber()); response.setPageSize(users.getSize()); response.setFirst(users.isFirst()); response.setLast(users.isLast()); return ResponseEntity.ok(response); }
这样返回的响应就只保留了前端真正需要的核心分页信息,看起来清爽多了~
内容的提问来源于stack exchange,提问作者Ilya Shaikovsky
相关产品推荐
相关产品推荐

