使用@RepositoryRestController与CollectionModel时响应缺失分页信息的解决方法
如何在@RepositoryRestController中给响应添加分页信息
问题场景
我在Spring Data开发中,Repository方法定义如下:
public Page<Order> findByStatusIn(List<OrderStatus> orderStatuses, Pageable pageable);
在标注了@RepositoryRestController的控制器中调用该方法:
Pageable paging = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC,"id")); Page<Order> myOrders = orderRepository.findByStatusIn(orderStatuses, paging);
随后将Page对象转换为CollectionModel并返回:
CollectionModel<Order> resources = CollectionModel.of(myOrders); resources.add(linkTo(methodOn(OrderController.class).userOrders(page,pageSize,currentUser)).withSelfRel()); return new ResponseEntity<>(resources,HttpStatus.OK);
得到的响应JSON内容正确,但缺少Spring Data Repository默认返回的分页元数据:
{ "_embedded": { "orders": [ { "orderId": 10011, "createdAt": "2022-05-18T16:28:19+05:30", "lastUpdatedAt": "2022-06-10T16:28:15+05:30", "createdBy": "User01", "status": "PENDING" }, { "orderId": 10012, "createdAt": "2017-05-03T14:28:19+05:30", "lastUpdatedAt": "2022-06-10T16:28:15+05:30", "createdBy": "User01", "status": "SHIPPED" } ] }, "_links": { "self": { "href": "http://localhost:8080/orders/userOrders?page=0&pageSize=11" } } }
期望添加的分页信息格式如下:
"page": { "size": 20, "totalElements": 20, "totalPages": 1, "number": 0 }
解决方案
直接使用CollectionModel只会转换集合数据,不会自动携带分页元数据。需要改用Spring HATEOAS提供的PagedModel,它专门用于处理分页响应,会自动封装分页信息。
修改转换代码如下:
// 使用PagedModel替代CollectionModel,传入分页元数据 PagedModel<Order> resources = PagedModel.of( myOrders.getContent(), new PagedModel.PageMetadata( myOrders.getSize(), myOrders.getNumber(), myOrders.getTotalElements(), myOrders.getTotalPages() ) ); // 添加自链接 resources.add(linkTo(methodOn(OrderController.class).userOrders(page,pageSize,currentUser)).withSelfRel()); return new ResponseEntity<>(resources, HttpStatus.OK);
关键说明
PagedModel是Spring HATEOAS为分页场景设计的模型,会自动将分页元数据封装到响应的page字段中,格式与Spring Data Repository默认返回一致。PageMetadata的构造参数依次对应:每页大小、当前页号、总元素数、总页数,这些参数均可直接从查询得到的Page<Order>对象中获取。
修改后,响应就会包含所需的分页信息。
内容的提问来源于stack exchange,提问作者Shoreki
相关产品推荐
相关产品推荐

