【问题标题】:How to customize response in Spring Integration using WebFlux when a specific error occurs?发生特定错误时,如何使用 WebFlux 在 Spring Integration 中自定义响应?
【发布时间】:2021-08-03 13:49:51
【问题描述】:

我正在尝试使用WebFlux.outboundGateway 调用上的子流程来制定基于WebClient 的处理和丰富方法。

我的目的是处理远程端发生 HTTP/404 的情况。在这种情况下,我将使用可以在下游处理并适当路由的已知文档来处理错误。

.enrich( e ->
    e.requestSubFlow(
        sf -> sf.handle(
                WebFlux.outboundGateway("http://example.com/entity/name/{entityName}")
                    .uriVariable("entityName", "payload")
                    .httpMethod(HttpMethod.GET)
                    .expectedResponseType(String.class),
                ec -> ec.customizeMonoReply(
                    (message,mono) ->
                        mono.onErrorResume(
                            WebClientResponseException.NotFound.class,
                            Mono.just("{ \"id\": -1, \"name\": null }")
                                .flatMap(s -> 
                                    ServerResponse.ok()
                                        .contentType(MediaType.APPLICATION_JSON)
                                        .bodyValue(s)
                                )
                        )
                )
            )
    )
    .headerExpression("result", "payload")
)

我得到的是类似于以下的编译错误:

The method onErrorResume(Class<E>, Function<? super E,? extends Mono<? extends capture#3-of ?>>) in the type Mono<capture#3-of ?> is not applicable for the arguments (Class<WebClientResponseException.NotFound>, Mono<Object>)

我什至不知道我是否正确地处理了这个问题。任何建议将不胜感激。

为了帮助解决这个问题,我发布了整个代码 https://github.com/djgraff209/so68637283

编辑 8/6:

感谢@artem-bilan 对此的反馈。第一点是onErrorResume 的第二个参数不是函数。我已经更正了。

接下来,异常匹配结果不正确。一个通用的WebClientResponseException 被抛出,而不是一个更具体的WebClientResponseException.NotFound,这是我所希望的。

我将逻辑更新如下。此代码可在引用的 GitHub 项目中找到。

    ec -> ec.customizeMonoReply(
        (Message<?> message, Mono<?> mono) -> 
            mono.onErrorResume(
                WebClientResponseException.class,
                ex1 -> {
                    Mono<?> exReturn = mono;
                    if( ex1.getStatusCode() == HttpStatus.NOT_FOUND ) {
                        exReturn = Mono.just(defaultPayload);
                    }
                    return (Mono)exReturn;
                }
            )
    )

虽然这可行,但它并不像我想要的那样干净。我不喜欢在其中放置一个 if 条件来通过 HttpStatus 解析异常类型,而不仅仅是将其解析为特定的类。

这可能是一个很好的错误/增强候选者。

已提交#3610

【问题讨论】:

    标签: spring-integration spring-webflux spring-integration-dsl


    【解决方案1】:

    我觉得应该是这样的:

    mono.onErrorResume(
        WebClientResponseException.class,
        ex1 -> Mono.just(ex1)
                .filter(ex -> ex.getStatusCode() == HttpStatus.NOT_FOUND)
                .map(ex -> "default")
                .switchIfEmpty((Mono) mono))
    

    onErrorResume() 的第二个参数应该是 Function,而不是你目前的常量。

    【讨论】:

    • 我尝试按照您的建议进行转换,但得到了:Type mismatch: cannot convert from Mono&lt;Object&gt; to Mono&lt;? extends capture#3-of ?&gt;
    • 是的...我明白你的意思。 Mono.just() 必须转换为 (Mono)。查看我的答案的编辑。我看到了customizeMonoReply() 的泛型修复。因此,在未来的版本中,您将不需要 (Mono) 演员表。
    • 我刚刚在引用的 github 上更新了代码库 - 很快更新了主帖。我希望您了解这是如何工作的。
    • .DefaultWebClientDefaultResponseSpec.statusHandlers。可能以某种方式插入了其他一些处理程序而不是DEFAULT_STATUS_HANDLER,它具有基于状态的特定异常的ClientResponse::createException 回调。或者您的状态以其他格式返回。这是我们需要调试的。也许你可以分享一些简单的项目来玩。
    • 查看已编辑的代码 sn-p 如何避免代码中出现 if..else
    猜你喜欢
    • 2023-01-14
    • 2019-04-03
    • 2019-03-24
    • 2020-12-20
    • 2019-09-23
    • 2020-10-03
    • 2020-06-09
    • 2012-02-21
    • 2020-07-25
    相关资源
    最近更新 更多