Spring Pageable排序公开了dao的内部命名

Twa*_*jes 5 java dao dto spring-data-jpa spring-data-rest

我正在使用Spring和Spring存储库构建其余的微服务。我想让客户端控制分页和排序(使用spring-data-rest)。

public PagedResources<TestDto> find(
    @PageableDefault(page = 0, size = 50) final Pageable pageable,
    final PagedResourcesAssembler<Test> assembler) {

    final Page<Test> pagedResults = testRepository.findAll(pageable);

    return assembler.toResource(pagedResults, testResourceAssembler);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码很好用,但是我不满意排序是耦合到我的dao层而不是dto层。例:

http://localhost:8080/my-service/test?size=100&page=0&sort=statusCode,asc
Run Code Online (Sandbox Code Playgroud)

json响应(DTO):

{
  "links": [
    ...
    ...
  ],
  "content": [
    {
      "id": 4
      "status": "OK"
      "links": []
    }
  ],
  "page": {
    "size": 100,
    "totalElements": 1,
    "totalPages": 1,
    "number": 0
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,请求url中的“ statusCode”排序与响应dto中相应的“ status”之间的区别。从客户的角度来看,这是不合逻辑的。现在,我还公开了该服务的一些内部信息。我无法更改服务的实现,因为它可以由客户端使用,并且在更改名称后会破坏旧的请求。

当我添加一个自定义映射以处理searchrequest中的状态码与状态的差异时:

private PageRequest getPageRequest(final Pageable pageable) {
    final List<Order> newOrder = new ArrayList<>();
    for (final Order order : pageable.getSort()) {
    if (daoToJpaMapping.containsKey(order.getProperty())) {
            newOrder.add(new Order(order.getDirection(), daoToJpaMapping.get(order.getProperty())));
        } else {
            throw new OngeldigSortProperty(order.getProperty() + " is niet toegestaan als sorteerproperty");
        }
    }
    final PageRequest pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(newOrder));

    return pageRequest;
}
Run Code Online (Sandbox Code Playgroud)

它因hal响应而对我适得其反,因为它包含基于jpa名称的完整URL:

{
  "links": [
    {
      "rel": "first",
      "href": "http://localhost:8080/my-service/test?page=0&size=100&sort=statusCode,asc",
...
Run Code Online (Sandbox Code Playgroud)

除了自定义sort,page和size参数外,我找不到解决此问题的方法。但是建立一个自定义的sort属性,使其与Spring版本一样好,就像重新发明轮子一样。这是否意味着我要滥用弹簧功能?使用DTO的工作相当普遍,所以我很惊讶没有(春季)教程解释您的其余界面中的分页涵盖了这一部分。有解决方案吗?

Tit*_*lum 0

我在我的项目中遇到了同样的问题,并通过完全分离控制器和数据层来解决它:

控制器层对象:

public class QueryOptionsDTO {
  int pageNumber;
  int pageSize;
  String sortField;
  String sortDirection

  public Pageable toPageable() {
    Sort sort = Sort.by(sortField);
    if (sortDirection.equals("asc")) {
      sort = sort.ascending();
    } else {
      sort = sort.descending();
    }
    return PageRequest.of(pageNumber, pageSize, sort);
  }
}
Run Code Online (Sandbox Code Playgroud)
public class ResultPageDTO<YourObjectDTO> {
  List<YourObjectDTO> results;
  int pageNumber;
  int pageSize;
  int totalPages;
  int totalSize;

  public <YourDomainObject> ResultPageDTO<YourObjectDTO> from(Page page, Function<YourDomainObject, YourObjectDTO> mapper) {
    // Custom logic to map to ResultPageDTO<YourObjectDTO>
  }
}
Run Code Online (Sandbox Code Playgroud)
@GetMapping
public ResultPageDTO<YourObjectDTO> find(@RequestParam QueryOptionsDTO queryOptionsDTO) {

    PageResult<YourObject> pagedResults = objectQueryService.find(queryOptionsDTO.toPageable());

    return ResultPageDTO.of(pagedResults);
}
Run Code Online (Sandbox Code Playgroud)

这是伪代码,只是为了向您展示如何实现它。