当前位置: 首页 > 知识库问答 >
问题:

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

贺宜修
2023-03-14

我试图获取值(字符串)使用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]

块方法参考-https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-client-synchronous

共有1个答案

芮星海
2023-03-14

当使用Webflux时,整个想法是不阻塞-如果阻塞,将导致巨大的性能问题(请参阅此处的相关答案,解释原因),因此框架明确禁止它,如果尝试,将引发异常

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

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

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

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

 类似资料:
  • 我是JS的学生。我有一段代码返回了一个错误。 这是返回的语法错误。你们能解释一下我做错了什么吗?

  • 问题内容: 我有一类这样的方法: 我如何在另一个类中调用此方法? 问题答案: 1. 如果要从中调用该方法的类位于同一包中,则创建该类的实例并调用该方法。 2. 使用 3. 最好有个赞等等。 例如:

  • 在执行基本方法重载程序时,我始终收到以下错误: sh-4.3 $ javac HelloWorld . Java < br > HelloWorld . Java:10:错误:方法show()已在类hello world中定义< br > static void show()< br > hello world . Java:25:错误:方法show(int,int)已在类hello world中

  • 问题内容: 我正在编写一个Android 2.2应用程序,该应用程序将JSON严格性过帐到ReSTfull Web服务。 Fiddler对Web服务的调用具有与预期相同的Json返回,而对ASPX Web应用程序具有与预期的相同Json返回。 当我查看服务器日志时,可以看到服务器使用307重定向响应初始POST动词,然后立即响应GET和405错误。 Fiddler和aspx应用程序记录一个307重

  • 我有一个验证方法,将两个输入作为开始日期和结束日期,并检查结束日期是否有效,即在开始日期之后。我使用Calendar方法获取两个日期的毫秒数并得到差值。如果差值为负值,则其无效的结束日期,即结束日期早于开始日期。结束日期的毫秒值应始终大于开始日期。但在某些情况下,在开始日期的情况下,getTimeInMillis()会提供更大的值。 这是我的代码: 输出为: 这里2015-01-31是开始日期,2

  • 我从教程中感觉到,返回一个可丢弃的,不应该改变方法返回类型。 以下是我的尝试: 使用时,一切都很好,直到我添加,然后函数返回类型更改为