Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何正确地从WebFlux客户端排出/释放响应主体?_Java_Spring Webflux_Project Reactor - Fatal编程技术网

Java 如何正确地从WebFlux客户端排出/释放响应主体?

Java 如何正确地从WebFlux客户端排出/释放响应主体?,java,spring-webflux,project-reactor,Java,Spring Webflux,Project Reactor,我正在使用Spring5反应堆栈中的WebFlux HTTP客户端访问外部REST服务。我想根据HTTP状态处理响应: 如果状态为2xx,我想返回带有反序列化响应体的Mono 如果状态为404,我想删除响应正文并立即返回空的Mono 对于任何其他状态,我希望删除响应正文并返回带有MyBusinessException的错误消息 我的代码如下所示: webClient.get() .uri("/search") .syncBody(request) .exchange()

我正在使用Spring5反应堆栈中的WebFlux HTTP客户端访问外部REST服务。我想根据HTTP状态处理响应:

  • 如果状态为2xx,我想返回带有反序列化响应体的
    Mono

  • 如果状态为404,我想删除响应正文并立即返回空的
    Mono

  • 对于任何其他状态,我希望删除响应正文并返回带有
    MyBusinessException
    的错误消息

  • 我的代码如下所示:

    webClient.get()
        .uri("/search")
        .syncBody(request)
        .exchange()
        .flatMap { response ->
            when {
                response.statusCode().is2xxSuccessful -> response.bodyToMono(MyResponse::class.java)
                response.statusCode() == NOT_FOUND -> Mono.empty()
                else -> MyBusinessException().toMono<MyResponse>()
            }
         }
    
    webClient.get()
    .uri(“/search”)
    .syncBody(请求)
    .exchange()
    .flatMap{响应->
    什么时候{
    response.statusCode().is2xxsuccesful->response.bodyToMono(MyResponse::class.java)
    response.statusCode()==未找到->Mono.empty()
    else->MyBusinessException().toMono()
    }
    }
    
    我不想在我不需要的时候浪费时间来接收和处理回复体。JavaDoc for
    exchange()
    方法状态

    您必须始终使用响应的body或entity方法之一,以确保释放资源


    如果我想立即清空响应体并返回结果,我应该如何做呢?

    需要清空响应,以便连接可以在将来的请求中重用(即http保持活动/持久连接)

    要返回在主体排空后完成的空
    Mono
    (忽略错误),请执行以下操作:

    //使用WebFlux>=5.2
    response.releaseBody()
    //忽略错误
    .onErrorResume(异常->Mono.empty());
    //使用WebFlux<5.2
    response.body(BodyExtractors.toDataBuffers())
    //释放数据缓冲区
    .doOnNext(数据缓冲区::发布)
    //忽略错误
    .onErrorResume(异常->Mono.empty())
    //返回一个空单声道
    .然后();
    
    要返回一个立即完成的空
    Mono
    ,并在后台异步排空正文(忽略错误),请执行以下操作:

    //使用WebFlux>=5.2
    Mono.empty()
    .doOnSubscribe(s->
    //排空身体
    response.releaseBody()
    //在单独的计划程序上启动排水
    .subscribeOn(Schedulers.parallel())
    //订阅,并忽略错误
    .subscribe())
    //使用WebFlux<5.2
    Mono.empty()
    .doOnSubscribe(s->
    //排空身体
    response.body(BodyExtractors.toDataBuffers())
    //释放数据缓冲区
    .doOnNext(数据缓冲区::发布)
    //在单独的计划程序上启动排水
    .subscribeOn(Schedulers.parallel())
    //订阅,并忽略错误
    .subscribe())
    
    我仍然推荐第一个选项,因为它可以立即释放资源,并且可能是
    WebClient
    开发人员在编写它和记录它的使用情况时想到的


    我从未在生产系统中使用过第二个选项,所以请自己进行测试,以确保http连接池按预期运行。如果使用reactor netty,您可以在
    reactor.netty.resources.PooledConnectionProvider上启用调试日志记录来比较这两种方法。

    谢谢。此
    Mono
    将在收到整个响应后完成。如何返回在后台使用响应时立即完成的空
    Mono
    ?这更多的是关于反应堆的问题,但我对这个主题还不熟悉,我害怕犯一些错误,比如阻塞事件循环,没有正确订阅etcAnswer,编辑后包含了在后台进行排水的示例。