发生特定错误时如何使用 WebFlux 在 Spring 集成中自定义响应?

How to customize response in Spring Integration using WebFlux when a specific error occurs?

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

我的目的是处理远程端发生 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 解决异常类型而不是仅仅将其解决为特定的 class.

感到兴奋

这可能是 bug/enhancement 的一个很好的候选者。

已提交#3610

我想一定是这样的:

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

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