如何从 Spring WebClient 获得响应 json

How to get response json from Spring WebClient

我一直在尝试按照最简单的教程学习如何使用 WebClient,据我所知,与 RestTemplate 相比,它是下一个最棒的东西。

例如,https://www.baeldung.com/spring-5-webclient#4-getting-a-response

所以当我尝试用 https://petstore.swagger.io/v2/pet/findByStatus?status=available 做同样的事情时,应该 return 一些 json,

WebClient webClient = WebClient.create();
webClient.get().uri("https://petstore.swagger.io/v2/pet/findByStatus?status=available").exchange().block();

我完全不知道如何从生成的 DefaultClientResponse 对象开始。到物理反应体应该不会这么费劲,但我跑题了。

如何使用我提供的代码获取响应正文?

以下是使用 RestTemplate

发出请求的方法
String json = new RestTemplate()
    .getForEntity("https://petstore.swagger.io/v2/pet/findByStatus?status=available")
    .getBody();

以下是使用 requests

发出请求的方法
import requests

json = requests.get("https://petstore.swagger.io/v2/pet/findByStatus?status=available")
    .content

以下是使用 WebClient

发出请求的方式
String json = WebClient.create()
    .get()
    .uri("https://petstore.swagger.io/v2/pet/findByStatus?status=available")
    .exchange()
    .block()
    .bodyToMono(String.class)
    .block();

以您当前拥有的形式,并解释其行为..

WebClient webClient = WebClient.create();
webClient.get()
         .uri("https://petstore.swagger.io/v2/pet/findByStatus?status=available")
         .exchange()
         .block();

block() 通过内部同步订阅 Mono 来启动请求,return 生成结果 ClientResponse。您还可以通过 exchange() 方法在 Mono return 上调用 subscribe() 来异步处理此问题,而不是 block().

在当前的形式中,在 block() 之后,您现在拥有关于 ClientResponse object 中响应的所有元数据(即来自响应 header) ,包括成功状态。这并不意味着响应 body 已经完成。如果您不关心响应负载,您可以确认成功并保留它。

如果您想进一步查看响应 body,您需要将响应 body 流转换为一些 class。在这一点上,您可以决定是要将所有内容读入带有 bodyToMono 的单个 Mono 还是带有 bodyToFlux 的 objects (Flux) 流中,例如在响应是 JSON 数组的情况下,可以将其解析为单独的 Java objects.

但是,在您的情况下,您只想查看 JSON as-is。所以转换为 String 就足够了。您只需使用 bodyToMono 即可 return a Mono object.

WebClient webClient = WebClient.create();
String responseJson = webClient.get()
                               .uri("https://petstore.swagger.io/v2/pet/findByStatus?status=available")
                               .exchange()
                               .block()
                               .bodyToMono(String.class)
                               .block();

这里使用block()等待响应payload到达并解析为String,但也可以subscribeMono接收它在完成时会反应。

需要注意的一件事是可以使用 retrieve() 代替 exchange() 来简化 ClientResponse。在这种情况下,您让默认行为处理错误响应。使用 exchange() 将响应 ClientResponse 上的错误响应的所有责任都放在应用程序上。阅读更多 in the Javadocretrieve() 版本如下所示。无需 block(),因为您只关心响应数据。

WebClient webClient = WebClient.create();
String responseJson = webClient.get()
                               .uri("https://petstore.swagger.io/v2/pet/findByStatus?status=available")
                               .retrieve()
                               .bodyToMono(String.class)
                               .block();