问题描述
我正在寻找使用 WebFlux 进行错误处理的简单示例。我在网上阅读了很多东西,但找不到适合我想要的东西。
我正在使用 Spring Boot 2.45
我正在调用这样的服务:
Mono<ResponSEObject> mono = webClient.post()
.uri(url.toString())
.header("Authorization",authToken)
.body(Mono.just(contract),contract.getClass())
.retrieve()
.bodyToMono(ResponSEObject.class);
我所有的服务都返回反序列化为 RespoSEObject 的 Json,看起来像这样:
"success" : true,"httpStatus": 200,"messages" : [
"informational message or,if not 200,then error messages"
],result: {
"data": {}
}
data 只是作为服务调用结果的对象的映射。 如果有错误,显然success 是假的。
当我最终执行 ResponSEObject response = mono.block()
时,我希望每次都获得一个 ResponSEObject,即使出现错误也是如此。即使我的服务返回 400 的 http 状态,我的服务也会返回一个 ResponSEObject,但 WebFlux 似乎拦截了它并抛出异常。显然,也可能有 400 和 500 错误甚至没有调用服务。但是我仍然想将我收到的任何消息包装到一个 ResponSEObject 中。如何消除所有异常并始终返回 ResponSEObject?
更新 只是想澄清一下,该服务本身不是 Reactive Webflux 服务。 不是返回一个 Mono。相反,它正在调用其他 Restful 服务,我想使用 Webflux 来做到这一点。所以我所做的就是调用外部服务,然后这个服务做了一个block()。在大多数情况下,我会调用多个服务,然后执行 Mono.zip 并调用 block() 以等待所有服务。
这似乎是我想要做的:Spring Webflux : Webclient : Get body on error,但仍然无法让它工作。不确定什么是 exchange()
解决方法
处理此问题的正确方法是通过 .onErrorResume
,它允许您在发生任何错误时使用函数订阅后备发布者。您可以查看生成的异常并返回自定义回退响应。
你可以这样做:
Mono<ResponseObject> mono = webClient.post()
.uri(url.toString())
.header("Authorization",authToken)
.bodyValue(contract)
.exchangeToMono(response -> {
if (response.statusCode().equals(HttpStatus.OK)) {
return response.bodyToMono(ResponseObject.class);
}
else if (response.statusCode().is4xxClientError()) {
return response.bodyToMono(ResponseObject.class);
}
else {
Mono<WebClientResponseException> wcre = response.createException();
// examine wcre and create custom ResponseObject
ResponseObject customRO = new ResponseObject();
customRO.setSuccess(false);
customRO.setHttpStatus(response.rawStatusCode());
// you can set more default properties in response here
return Mono.just( customRO );
}
});
此外,您不应在 Java 代码的任何地方使用 .block()
。只需确保从您的 REST 控制器返回 Mono<ResponseObject>
。如果您想在返回客户端之前检查响应,您可以在管道末尾(紧跟在 .map()
处理程序之后)的 .onErrorResume
处理程序中执行此操作
.map(response -> {
// examine content of response
// in the end just return it
return response;
});