Spring Boot控制器层不使用Pageable实现分页及解决排序问题
控制器层不使用Pageable实现分页的解决方案
问题说明
我们在数据层使用Pageable对象处理分页,但希望控制器层不直接依赖该对象。尝试用以下参数接收分页信息时遇到排序解析问题:
@RequestParam(required = false, defaultValue = "0") Integer page, @RequestParam(required = false, defaultValue = "20") Integer size, @RequestParam(required = false) String... sort
Spring要求排序参数为id,ASC这样的键值对格式,但String... sort会将传入的id,ASC拆分为两个独立的字符串项,无法正确解析排序规则。
可行解决方案
1. 自定义控制器分页参数DTO
创建专门用于控制器层的分页参数类,统一接收分页和排序信息:
public class PageRequestDTO { private Integer page = 0; private Integer size = 20; private List<String> sort; // 省略getter、setter及构造方法 }
在控制器中使用该DTO接收参数,并转换为数据层需要的Pageable对象:
@GetMapping("/data") public ResponseEntity<Page<Data>> getData(PageRequestDTO pageRequestDTO) { Pageable pageable = PageRequest.of( pageRequestDTO.getPage(), pageRequestDTO.getSize(), parseSort(pageRequestDTO.getSort()) ); Page<Data> dataPage = dataService.getData(pageable); return ResponseEntity.ok(dataPage); } // 自定义排序解析方法 private Sort parseSort(List<String> sortParams) { if (sortParams == null || sortParams.isEmpty()) { return Sort.unsorted(); } List<Sort.Order> orders = new ArrayList<>(); for (String param : sortParams) { String[] parts = param.split(","); if (parts.length == 2) { String field = parts[0].trim(); Sort.Direction direction = Sort.Direction.fromString(parts[1].trim().toUpperCase()); orders.add(new Sort.Order(direction, field)); } } return Sort.by(orders); }
前端传参时,需传递多个sort参数,例如:?page=0&size=10&sort=id,ASC&sort=createTime,DESC。
2. 直接使用List接收排序参数
无需自定义DTO,将排序参数类型改为List<String>,Spring会自动将多个sort参数解析为完整的键值对列表:
@GetMapping("/data") public ResponseEntity<Page<Data>> getData( @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size, @RequestParam(required = false) List<String> sort ) { Sort parsedSort = parseSort(sort); // 复用上述parseSort方法 Pageable pageable = PageRequest.of(page, size, parsedSort); Page<Data> dataPage = dataService.getData(pageable); return ResponseEntity.ok(dataPage); }
3. 直接接收Spring的Sort对象
Spring支持直接在控制器层接收Sort对象,自动解析符合格式的排序参数,无需手动解析:
@GetMapping("/data") public ResponseEntity<Page<Data>> getData( @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size, @RequestParam(required = false) Sort sort ) { Pageable pageable = PageRequest.of( page, size, sort != null ? sort : Sort.unsorted() ); Page<Data> dataPage = dataService.getData(pageable); return ResponseEntity.ok(dataPage); }
这种方式下,前端传参规则保持不变,Spring会自动将sort=id,ASC&sort=name,DESC解析为Sort对象。
内容的提问来源于stack exchange,提问作者Maksym Kruhovykh
相关产品推荐
相关产品推荐

