Webclient 发送带有 get 请求的请求体

Webclient sending request body with get request

我有一个名为 carrental-crud 的 spring-boot 项目,带有 h2 内存数据库,我想从另一个名为 carrental-api.[=16 的项目访问端点之一=]

我在我的其他端点上为此使用了 webClientBuilder,但是当我尝试在邮递员中使用它时,它会抛出错误请求状态 500。

我使用 JPArepository 通过查询访问 h2 数据库,这就是我的 orderRepository 的样子:

@Transactional
@Query(nativeQuery = true,value = "select count(*) from TBL_ORDER WHERE CUSTOMER_ID=?1")
public int getTotalOrders(long customerId);

然后在我的 adminCustomerService class 中,我这样使用它:

public int getTotalOrders(long customerId) {
    loggerService.writeLoggerMsg("LISTED TOTAL ORDERS FOR A CUSTOMER");
    
    return orderRepository.getTotalOrders(customerId);
}

然后在我的 adminCustomerController 中:

@GetMapping(path = "/totalorders")
public int getTotalOrders(@RequestBody Customer customer) {
    return adminCustomerService.getTotalOrders(customer.getCustomerId());
}

在我的邮递员请求正文中,我写:

{
  "customerId": 2
}

这在我的 carrental-crud 中有效,但我如何在我的 carrental-api 中重新创建它?

并在邮递员中使用相同的请求正文,但我一直收到错误状态 500 错误请求

编辑: 我设法通过使用参数而不是请求正文使其工作。

这是我的 adminCustomerService 的样子:

public int getTotalOrders(long customerId) {
   int orders = webClientBuilder.build()
            .get()
            .uri("http://localhost:8081/crud/v1/totalorders/" + customerId)
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference<Integer>() {})
            .log()
            .block();
    return orders;
}

还有我的 adminCustomerController:

@GetMapping(path = "/totalorders/{customerId}")
public int getTotalOrders(@PathVariable long customerId) {

    return adminCustomerService.getTotalOrders(customerId);
}

问题在于,您只是在编程调用中将 customerId 作为 Long 发送,而您应该发送类似于您显示的 JSON 的内容。解决这个问题的最简单方法是创建一个 class 匹配这样的 JSON 结构:

public class CustomerRequest {
    private long customerId;

    public CustomerRequest(long customerId) {
        this.customerId = customerId;
    }

    public long getCustomerId() {
        return customerId;
    }
}

然后你需要在调用API时创建这样的class实例,如下所示:

public Flux<Integer> getTotalOrders(long customerId) {
    loggerService.writeLoggerMsg("LISTED TOTAL ORDERS FOR A CUSTOMER");

    return ((RequestBodySpec) webClientBuilder
            .build()
            .get()
            .uri("localhost:8081/crud/v1/totalorders"))
            .body(Flux.just(new CustomerRequest(customerId)), CustomerRequest.class)
            .retrieve()
            .bodyToFlux(Integer.class);
}

不过,我建议您在端点中使用更多 RESTful 方法,并在 GET 请求中使用路径参数而不是请求正文。大致如下:

@GetMapping(path = "/customers/{customerId}/total-orders")
public int getTotalOrders(@PathVariable long customerId) {
    return adminCustomerService.getTotalOrders(customerId);
}

然后您将向此端点发出如下请求:

public Flux<Integer> getTotalOrders(long customerId) {
    loggerService.writeLoggerMsg("LISTED TOTAL ORDERS FOR A CUSTOMER");

    return webClientBuilder
            .build()
            .get()
            .uri("localhost:8081/crud/v1/customers/{customerId}/total-orders", customerId))
            .retrieve()
            .bodyToFlux(Integer.class);
}

我建议您阅读以下在线资源: