[英]Get API response error message using Web Client Mono in Spring Boot
I am using webflux Mono (in Spring boot 5) to consume an external API. 我使用webflux Mono(在Spring boot 5中)使用外部API。 I am able to get data well when the API response status code is 200, but when the API returns an error I am not able to retrieve the error message from the API.
当API响应状态代码为200时,我能够很好地获取数据,但是当API返回错误时,我无法从API检索错误消息。 Spring webclient error handler always display the message as
Spring webclient错误处理程序始终将消息显示为
ClientResponse has erroneous status code: 500 Internal Server Error
, but when I use PostMan the API returns this JSON response with status code 500. ClientResponse has erroneous status code: 500 Internal Server Error
,但是当我使用PostMan时,API会返回状态代码为500的JSON响应。
{
"error": {
"statusCode": 500,
"name": "Error",
"message":"Failed to add object with ID:900 as the object exists",
"stack":"some long message"
}
}
My request using WebClient is as follows 我使用WebClient的请求如下
webClient.getWebClient()
.post()
.uri("/api/Card")
.body(BodyInserters.fromObject(cardObject))
.retrieve()
.bodyToMono(String.class)
.doOnSuccess( args -> {
System.out.println(args.toString());
})
.doOnError( e ->{
e.printStackTrace();
System.out.println("Some Error Happend :"+e);
});
My question is, how can I get access to the JSON response when the API returns an Error with status code of 500? 我的问题是,当API返回状态代码为500的错误时,如何才能访问JSON响应?
If you want to retrieve the error details: 如果要检索错误详细信息:
WebClient webClient = WebClient.builder()
.filter(ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
if (clientResponse.statusCode().isError()) {
return clientResponse.bodyToMono(ErrorDetails.class)
.flatMap(errorDetails -> Mono.error(new CustomClientException(clientResponse.statusCode(), errorDetails)));
}
return Mono.just(clientResponse);
}))
.build();
with 同
class CustomClientException extends WebClientException {
private final HttpStatus status;
private final ErrorDetails details;
CustomClientException(HttpStatus status, ErrorDetails details) {
super(status.getReasonPhrase());
this.status = status;
this.details = details;
}
public HttpStatus getStatus() {
return status;
}
public ErrorDetails getDetails() {
return details;
}
}
and with the ErrorDetails
class mapping the error body 并使用
ErrorDetails
类映射错误体
Per-request variant: 每请求变体:
webClient.get()
.exchange()
.map(clientResponse -> {
if (clientResponse.statusCode().isError()) {
return clientResponse.bodyToMono(ErrorDetails.class)
.flatMap(errorDetails -> Mono.error(new CustomClientException(clientResponse.statusCode(), errorDetails)));
}
return clientResponse;
})
Just as @Frischling suggested, I changed my request to look as follows 就像@Frischling建议的那样,我改变了我的请求,如下所示
return webClient.getWebClient()
.post()
.uri("/api/Card")
.body(BodyInserters.fromObject(cardObject))
.exchange()
.flatMap(clientResponse -> {
if (clientResponse.statusCode().is5xxServerError()) {
clientResponse.body((clientHttpResponse, context) -> {
return clientHttpResponse.getBody();
});
return clientResponse.bodyToMono(String.class);
}
else
return clientResponse.bodyToMono(String.class);
});
I also noted that there's a couple of status codes from 1xx to 5xx, which is going to make my error handling easier for different cases 我还注意到有一些从1xx到5xx的状态代码,这将使我的错误处理更容易在不同的情况下
Look at .onErrorMap()
, that gives you the exception to look at. 查看
.onErrorMap()
,它为您提供了查看的异常。 Since you might also need the body() of the exchange() to look at, don't use retrieve, but 因为您可能还需要查看exchange()的body(),所以不要使用retrieve,而是
.exchange().flatMap((ClientResponse) response -> ....);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.