问题描述
我已经阅读了很多文档以及与此有关的其他stackoverflow问题,但似乎无法使我的代码正常工作。
基本上,我有一个WebClient发出POST请求。
- 如果响应状态为200,则使用另一个WebClient再次调用另一个端点。在第二次webclient调用之后,返回一个字符串。
- ELSE我只是从方法中返回一个字符串,例如“无法创建订单。”
足够简单。 (这都是在单独的线程fyi中完成的,而不是在主线程中完成的。)
但是我注意到,如果我确实得到了500错误代码,则WebClient会引发异常。我想做的就是捕获异常并优雅地处理该异常,并返回一个字符串,例如“错误调用第一个端点等”。
这是我到目前为止所拥有的:
private String generateOrder(ImportedOrderDetails importedOrderDetails)
{
Order requestBody = generateRequestBody(importedOrderDetails);
OrderResponse responseForCreatingOrder = orderWebClient()
.post()
.body(Mono.just(requestBody),Order.class)
.retrieve()
.bodyToMono(OrderResponse.class)
.block();
if (responseForCreatingOrder.getResponseStatus().equals(SUCCESS))
{...other call using different webclient}
else{ return "Error creating order."}
当响应状态为200,但响应状态为500时,此方法工作正常。
OrderResponse是一个自定义对象。 orderWebClient()
只是一种返回包含baseUrl和标头等的预构建WebClient的方法。
我遇到了这个: Spring WebClient - How to handle error scenarios我确实尝试实现了它,但是由于不断获取以下内容,所以无法弄清楚将block方法放在哪里:
reactor.core.Exceptions$ReactiveException: java.lang.Exception
at reactor.core.Exceptions.propagate(Exceptions.java:393)
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:97)
at reactor.core.publisher.Mono.block(Mono.java:1680)
我不得不稍微修改一下代码以尝试实现该问题的答案:
private Mono<? extends Throwable> handleError(String message) {
log.error("====---"+message);
return Mono.error(Exception::new);
}
private String generateOrder(ImportedOrderDetails importedOrderDetails)
{
Order requestBody = generateRequestBody(importedOrderDetails);
Mono<OrderResponse> responseForCreatingDemo = orderWebClient()
.post()
.body(Mono.just(requestBody),Order.class)
.retrieve()
.onStatus(
(HttpStatus::is5xxServerError),(it -> handleError(it.statusCode().getReasonPhrase()))
)
.bodyToMono(OrderResponse.class);
System.out.println("-=-"+responseForCreatingDemo);
if (responseForCreatingOrder != null && responseForCreatingOrder.block().getHeader().getResponseStatus().equals(SUCCESS)){...}
错误来自if条件中的.block
部分。我相信这是一件很琐碎的事情,而且缺少大局。
有什么建议吗?
解决方法
您似乎有两种状态:
- 由协议本身定义的Http状态(请参见HTTP response status codes)
- 特定于您正在处理的应用程序的某些内容,封装在
OrderResponse
类中。
因此您必须处理两个“错误”而不是一个,可能的解决方案中的一个 看起来像
.retrieve()
.bodyToMono(OrderResponse.class)
// 4xx,5xx errors and return "Unable to create order" String instead
.onErrorContinue(WebClientResponseException.class,(ex,v) ->
Mono.just("Unable to create order"))
// if application specific status is not "ok" return "Unable to create order"
.map(it -> it.ok ? "Ok response" : "Unable to create order")
.block();
请注意,此代码示例将忽略异常,甚至不会记录该异常