发生特定错误时如何使用 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
,而不是目前为止的常量。
我正在尝试制定一种基于 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
,而不是目前为止的常量。