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

当服务器手动停止时,WebClientResponseException返回200 HTTP状态代码

柴琨
2023-03-14

目前,我正在尝试使用Flux通过WebClient从服务器端获取消息。我想检查我是否可以处理非2xx HTTP状态情况的异常。在接收消息期间,我会停止服务器。在这种情况下,我希望通过我的自定义异常获得500个状态代码,但它会通过我的自定义异常返回200个状态代码。

您可以在下面找到输出日志(粗体部分很重要)

**org.springframework.web.reactive.function.client.WebClientResponseException: 200 OK from GET serverUri; nested exception is reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response
    at org.springframework.web.reactive.function.client.WebClientResponseException.create(WebClientResponseException.java:229) ~[spring-webflux-5.3.18.jar:5.3.18]**
    at org.springframework.web.reactive.function.client.DefaultClientResponse.lambda$createException$1(DefaultClientResponse.java:207) ~[spring-webflux-5.3.18.jar:5.3.18]
    at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:106) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2194) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:74) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.Mono.subscribe(Mono.java:4400) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.Operators$MonoSubscriber.onError(Operators.java:1863) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:140) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onError(FluxContextWrite.java:121) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onError(FluxMapFuseable.java:334) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onError(FluxFilterFuseable.java:382) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.MonoCollect$CollectSubscriber.onError(MonoCollect.java:144) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:132) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:132) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.Operators.error(Operators.java:198) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.netty.channel.FluxReceive.startReceiver(FluxReceive.java:172) ~[reactor-netty-core-1.0.17.jar:1.0.17]
    at reactor.netty.channel.FluxReceive.subscribe(FluxReceive.java:143) ~[reactor-netty-core-1.0.17.jar:1.0.17]
    at reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:62) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.netty.ByteBufFlux.subscribe(ByteBufFlux.java:340) ~[reactor-netty-core-1.0.17.jar:1.0.17]
    at reactor.core.publisher.Mono.subscribe(Mono.java:4400) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onError(FluxConcatMap.java:263) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxBufferPredicate$BufferPredicateSubscriber.onError(FluxBufferPredicate.java:346) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxPeekFuseable$PeekFuseableConditionalSubscriber.onError(FluxPeekFuseable.java:553) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onError(FluxMapFuseable.java:334) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onError(FluxContextWrite.java:121) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onError(FluxPeekFuseable.java:903) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onError(FluxConcatArray.java:207) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.drainAsync(FluxFlattenIterable.java:321) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.drain(FluxFlattenIterable.java:686) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.onError(FluxFlattenIterable.java:257) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:132) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:132) ~[reactor-core-3.4.16.jar:3.4.16]
    at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:465) ~[reactor-netty-core-1.0.17.jar:1.0.17]
    at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:260) ~[reactor-netty-core-1.0.17.jar:1.0.17]
    at reactor.netty.channel.FluxReceive.onInboundError(FluxReceive.java:453) ~[reactor-netty-core-1.0.17.jar:1.0.17]
    at reactor.netty.channel.ChannelOperations.onInboundError(ChannelOperations.java:488) ~[reactor-netty-core-1.0.17.jar:1.0.17]
    at reactor.netty.http.client.HttpClientOperations.onInboundClose(HttpClientOperations.java:298) ~[reactor-netty-http-1.0.17.jar:1.0.17]
    at reactor.netty.channel.ChannelOperationsHandler.channelInactive(ChannelOperationsHandler.java:73) ~[reactor-netty-core-1.0.17.jar:1.0.17]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.handler.codec.http.HttpContentDecoder.channelInactive(HttpContentDecoder.java:235) ~[netty-codec-http-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelInactive(CombinedChannelDuplexHandler.java:418) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:392) ~[netty-codec-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:357) ~[netty-codec-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.handler.codec.http.HttpClientCodec$Decoder.channelInactive(HttpClientCodec.java:326) ~[netty-codec-http-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.CombinedChannelDuplexHandler.channelInactive(CombinedChannelDuplexHandler.java:221) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:813) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) ~[netty-common-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469) ~[netty-common-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500) ~[netty-transport-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) ~[netty-common-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.75.Final.jar:4.1.75.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.75.Final.jar:4.1.75.Final]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
    *__checkpoint ⇢ Body from GET <serverUri> [DefaultClientResponse]
    *__checkpoint ⇢ Body from GET <serverUri> [DefaultClientResponse]
Original Stack Trace: 2022-05-30 11:06:33.864 ERROR 14499 --- [ctor-http-nio-2] c.m.c.s.service.MyServiceClass      : Error receiving message.
**com.myProject.MyCustomisedException: The server responded with error [200] when attempting to sending response**
    at com.myProject.MyExceptionHandler……

以下是客户端代码:

webClient
        .get()
        .uri(serverUri)
        .header(headerName, headerValue)
        .retrieve()
        .bodyToFlux(MyType)
        .onErrorMap(
            WebClientResponseException.class, handleMyException());



messageStream.subscribe(m -> 
{
…
executorService.execute
( **operations with callback function** )
…
}
); 

在这种情况下,我错过了什么?

共有1个答案

冯风史
2023-03-14

您可能缺少以下内容:如果在服务器向客户端写入响应时突然停止服务器,那么在客户端读取响应时,这确实会导致类似I/O的异常

但这并没有改变服务器已经编写并向客户端发送HTTP状态和响应头的事实。决定HTTP响应应该是什么样子不是客户端的工作。服务器确实用HTTP 200 OK进行了响应,但在写入响应正文时发生了一些错误。

 类似资料:
  • 我有一个Restendpoint,如果没有产品,它将返回204,以及以下通用角度服务: 和 但是,当服务生成 204 代码时,我收到以下错误: TypeError:无法读取null的属性“status” 这怎么可能发生?如果 API 以 204 响应,为什么整个响应为空?

  • 我已经将我的应用程序升级到了API 26,我面临着一些新的后台执行限制问题。 在Oreo设备上,只要我的应用程序进入后台,我的应用程序就会因日志中写入的空闲状态而被操作系统停止: 然后,我尝试再次启动我的应用程序,最后一个活动被正确还原(包括其片段和所有显示的数据) 问题是我的服务没有重新启动。 它们都在onstart命令中返回START_STICKY,该命令应该告诉操作系统,服务在被终止后应该重

  • 本文向大家介绍基于C#实现Windows服务状态启动和停止服务的方法,包括了基于C#实现Windows服务状态启动和停止服务的方法的使用技巧和注意事项,需要的朋友参考一下 本文以实例形式展示了基于C#实现Windows服务状态启动和停止服务的方法。非常实用。分享给大家供大家参考之用。具体方法如下: 首先先引用: 然后在引用命名空间: 建立服务对象: 服务运行则停止服务: 服务停止则启动服务: 希望

  • 问题内容: 使用Twitter4j提供的代码示例,我想在收集到1000个状态列表后停止流,并返回此列表。我怎样才能做到这一点? 问题答案: 将异步代码强制进入同步模式不是一个好主意。换句话说:使您的check方法也异步,传递一个回调参数而不是返回一个值;并将回调传递给execRequest(只需s将对每个分配的调用替换为该回调)。正如Jai所建议的那样,您不一定需要在应用程序范围的事件总线上触发事

  • 我正在尝试使用BitBucket GIT存储库设置Jenkins,但Jenkins控制台总是给我以下错误代码: 我尝试过很多不同的方法,但总是失败。我的服务器上允许9418端口上的通信量。服务器处于1 Gbps连接上。