【问题标题】:Converting Mono to Pojo without block无阻塞地将 Mono 转换为 Pojo
【发布时间】:2018-11-12 15:58:48
【问题描述】:

有没有办法将 Mono 对象转换为 java Pojo? 我有一个连接到第 3 方 REST 服务的 Web 客户端,我必须提取该对象并询问它,而不是返回 Mono

我找到的所有示例都返回Mono<Pojo>,但我必须获取 Pojo 本身。目前,我是通过在 Pojo 上调用 block() 来实现的,但是有没有更好的方法来避免阻塞?

该块的问题是,在几次运行后,它开始抛出一些错误,例如块 Terminated with error。

 public MyPojo getPojo(){
     return myWebClient.get()
                .uri(generateUrl())
                .headers(createHttpHeaders(headersMap))
                .exchange()
                .flatMap(evaluateResponseStatus())
                .block();
}


private Function<ClientResponse, Mono<? extends MyPojo>> evaluateResponseStatus() {
      return response -> {
            if (response.statusCode() == HttpStatus.OK) {
                return response.bodyToMono(MyPojo.class);
            }
            if (webClientUtils.isError(response.statusCode())) {
                throw myHttpException(response);
                // This invokes my exceptionAdvice
                // but after few runs its ignored and 500 error is returned.
            }
            return Mono.empty();
        };
    }

【问题讨论】:

    标签: java spring-webflux project-reactor web-client


    【解决方案1】:

    阻止对反应流中的值进行操作不是一个好主意。 Project Reactor 为您提供了一系列运算符来处理流中的对象。

    在您的情况下,您可以编写getPojo() 方法,例如:

    public Mono<MyPojo> getPojo() {
         return myWebClient.get()
                .uri(generateUrl())
                .headers(createHttpHeaders(headersMap))
                .retrieve()
                .onStatus(status -> webClientUtils.isError(status), 
                          response -> Mono.error(myHttpException(response))
                .bodyToMono(MyPojo.class)
    }
    

    请注意,使用onStatus 方法,我们替换了您示例中的整个evaluateResponseStatus 方法。

    你可以像下面这样使用这个方法:

    // some method
    ...
    getPojo()
        .map(pojo -> /* do something with the pojo instance */)
    ...
    

    我强烈建议您查看 Project Reactor 文档中的 Transforming an existing sequence

    【讨论】:

    • 谢谢 MuratOzkan.. 会试试看.. 虽然我不想返回 Mono 它必须是 MyPojo 所以我想我可以在返回之前使用 map(pojo ->)?
    • 如果您可以在上下文中添加更多详细信息,那就太好了。但总的来说,阻塞流并不是一个好主意,必须避免。
    • 是的,我理解并希望避免阻塞。上下文是获取 MyPojo 并返回它而不是返回 Mono。如果值为 null,则 MyPojo 的一个字段进一步用于引发异常。
    • 我的意思是你想要完成什么?通常你不需要返回一个对象,你使用响应式操作。可能你误会了……
    • 对...我将尝试使用这些操作。非常感谢您的帮助。
    【解决方案2】:

    由于不推荐使用 Webclient.block(),从传入的 httpresponse 检索值的另一种方法是在调用应用程序中创建一个具有所需字段的 POJO。然后,一旦收到 Mono,使用 Mono.subscribe(),在 subscribe 中添加一个 lambda 函数,输入为 x,以使用 x.getters() 检索各个字段。这些值可以打印在控制台上或分配给本地 var 以进行进一步处理。这有两个方面的帮助:-

    1. 避免使用可怕的 .block()
    2. 在提取大量数据时保持异步调用。 这是实现预期结果的许多其他方法之一。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-17
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 2018-12-29
      • 2015-11-15
      • 2023-03-12
      相关资源
      最近更新 更多