【问题标题】:Sort passed in Pageable to Spring controller appends direction to property name, causing a SQL error在Pageable中传递给Spring控制器的排序将方向附加到属性名称,导致SQL错误
【发布时间】:2020-03-20 14:01:22
【问题描述】:

我需要从另一个 Spring Boot 应用程序调用我的 Spring Boot 应用程序中的可分页端点。我正在尝试将可分页选项从第一个应用程序传递到第二个应用程序,但我遇到了一个问题,即属性名称以 firstName: ASC 出现。将方向附加到该方向后,它将变为 firstName: ASC: ASC,这会导致 JPA 查询引发异常。

将可分页选项从我的第一个端点传递到我的第二个端点的正确方法是什么?

通话应用

@GetMapping("/v1/users")
    public Flux<User> getUsersByAccount(@RequestParam Long accountId,
                                        @PageableDefault(size = 10, sort = "firstName") Pageable pageable) {
        return userService.getUsersByAccount(accountId, pageable);
}
public Flux<User> getUsersByAccount(Long accountId, Pageable pageable) {
    int page = pageable.getPageNumber();
    int size = pageable.getPageSize();
    Sort sort = pageable.getSort();

    return webClient.backendService()
        .get().uri(builder -> builder
            .path("/rest/users")
            .queryParam("accountId", accountId)
            .queryParam("page", page)
            .queryParam("size", size)
            .queryParam("sort", sort)
            .build())
        .retrieve()
        .bodyToFlux(ContactInfo.class);
}

我将 Pageable 拆分为其组件,因为我不确定如何一次传递整个对象,因为它不是第二个应用程序中的命名参数。请注意,在这一点上,排序看起来很好,并且应该以firstNameASC 分别作为属性名称和方向的单独值显示。

被调用的应用

@GetMapping("/rest/users")
    public List<User> getUsersByAccount(@RequestParam Long accountId, Pageable pageable) {
        return userService.getUsersByAccount(accountId, pageable);
}

【问题讨论】:

  • 你能粘贴User类吗?
  • 你不能像这样传递Sort。您必须解构它并传递各个参数。
  • @M.Deinum 解构后我该怎么办;只是建立一个字符串数组?查看 Swagger 中解构的 Pageable,它包含 pagesizesorti.imgur.com/5yn1F7M.png
  • 是的,它需要排序,但您不能简单地输入Sort,因为它会调用toString,这不是正确的表示。您应该发送sort=firstname_asc,lastname_desc 或您正在使用的任何字段。
  • 啊,好吧。我尝试将其解构为["firstName, ASC"] 之类的字符串,但显然即使在数组元素中它也是对空间敏感的,因此创建了一个附加属性ASC。以["firstName,ASC"] 发送虽然有效。 ¯\_(ツ)_/¯

标签: java spring spring-boot pagination spring-webclient


【解决方案1】:

作为@M。 Deinum 提到,SorttoString() 不会产生可以直接序列化回Sort 对象的表示,(并且对象上没有这样的方法可以做到这一点)。

您可以像这样将其转换为适当的形式:

List<String> sorts = new ArrayList<>();
sort.forEach(order -> sorts.add(String.join(",", order.getProperty(), order.getDirection().toString())));
builder.queryParam("sort", sorts.toArray());

这会产生["propertyName,direction"] 的正确表示。

【讨论】:

    【解决方案2】:

    控制器我们可以如下捕获HttpServletRequest

    public ResponseEntity<Page<PriceBook>> getAll(HttpServletRequest servletRequest) {
    
        return new ResponseEntity<>(priceBookService.findAll(servletRequest), HttpStatus.OK);
    
    }
    

    如下使用queryString将所有请求参数传递给后端服务

    public PageableResponse<PriceBook> getPbAllWithFilter(HttpServletRequest servletRequest) {
    
        return webClient.get().uri(pbUrl.concat("?").concat(servletRequest.getQueryString()))
                        .accept(MediaType.APPLICATION_JSON)
                        .header(CORRELATION_ID, MDC.get(CORRELATION_ID_MDC))
                        .exchange()
                        .flatMap(this::getSubscriptionAll)
                        .block();
    
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-22
      • 2014-08-23
      • 2020-11-18
      • 2021-11-30
      • 1970-01-01
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多