gpt4 book ai didi

Spring-Boot WebClient block() 方法返回错误 java.lang.IllegalStateException

转载 作者:行者123 更新时间:2023-12-02 02:13:01 34 4
gpt4 key购买 nike

我正在尝试使用 Spring WebFlux WebClient 获取值(字符串),(使用 SpringBoot 版本 2.4.5,)

@GetMapping("/test")
public Mono<String> getData(){
WebClient webClient = WebClient.create("http://localhost:9999");
Mono<String> stringMono = webClient.get()
.uri("/some/thing")
.retrieve()
.bodyToMono(String.class);
stringMono.subscribe( System.out::println);
System.out.println("Value : " + stringMono.block()); // this doesn't work, expecting to return ResponseBody as "Hello World" ,
return stringMono;
}

但低于错误

2021-05-11 20:02:15.521 ERROR 55613 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [19114471-1]  500 Server Error for HTTP GET "/test"
java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-2
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:83) ~[reactor-core-3.4.3.jar:3.4.3]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ HTTP GET "/test" [ExceptionHandlingWebHandler]
Stack trace:
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:83) ~[reactor-core-3.4.3.jar:3.4.3]
at reactor.core.publisher.Mono.block(Mono.java:1703) ~[reactor-core-3.4.3.jar:3.4.3]
at com.example.demo.DemoApplication.getData(DemoApplication.java:28) ~[main/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$invoke$0(InvocableHandlerMethod.java:146) ~[spring-webflux-5.3.4.jar:5.3.4]
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:151) ~[reactor-core-3.4.3.jar:3.4.3]

block 方法引用 - https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-client-synchronous

最佳答案

当使用 Webflux 时,整个想法是您不要阻塞 - 如果您这样做会导致大量性能问题(请参阅解释原因的 here for a related answer),因此框架明确不允许它,如果你尝试抛出异常。

您也不应该手动订阅 - 虽然在响应式世界中不像阻塞那样是“大罪”,但这肯定是另一个危险信号。订阅由框架处理。您只需返回 Mono,Webflux 将在需要时订阅以处理您的请求。在您的情况下,您的手动订阅意味着整个链实际上将为每个请求执行 两次 - 一次将结果打印到终端,一次将结果返回到 /test 端点。

相反,如果你想要这样的“副作用”(当你有它时打印出值)那么你需要改变 react 链来这样做,使用 doOnNext()运算符(operator)。这意味着您可以执行以下操作:

return webClient.get()
.uri("/some/thing")
.retrieve()
.bodyToMono(String.class)
.doOnNext(s -> System.out.println("Value: " + s));

这将确保将值打印到终端,但不会阻塞,也不会手动订阅。

关于Spring-Boot WebClient block() 方法返回错误 java.lang.IllegalStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67490814/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com