在 Spring 引导中使用 Web Client Mono 获取 API 响应错误消息
Get API response error message using Web Client Mono in Spring Boot
我正在使用 webflux Mono(在 Spring boot 5 中)来使用外部 API。当 API 响应状态代码为 200 时,我能够很好地获取数据,但是当 API returns 出现错误时,我无法从 [=23= 检索错误消息]. Spring 网络客户端错误处理程序始终将消息显示为
ClientResponse has erroneous status code: 500 Internal Server Error
,但是当我使用 PostMan 时 API returns 这个 JSON 状态码为 500 的响应。
{
"error": {
"statusCode": 500,
"name": "Error",
"message":"Failed to add object with ID:900 as the object exists",
"stack":"some long message"
}
}
我使用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);
});
我的问题是,当出现 API returns 状态代码为 500 的错误时,如何访问 JSON 响应?
看.onErrorMap()
,给你例外看。由于您可能还需要查看 exchange() 的 body(),因此不要使用 retrieve,而是
.exchange().flatMap((ClientResponse) response -> ....);
正如@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);
});
我还注意到有从 1xx 到 5xx 的几个状态代码,这将使我在不同情况下更容易处理错误
如果您想检索错误详细信息:
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();
和
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;
}
}
并与 ErrorDetails
class 映射错误主体
每个请求变体:
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;
})
我正在使用 webflux Mono(在 Spring boot 5 中)来使用外部 API。当 API 响应状态代码为 200 时,我能够很好地获取数据,但是当 API returns 出现错误时,我无法从 [=23= 检索错误消息]. Spring 网络客户端错误处理程序始终将消息显示为
ClientResponse has erroneous status code: 500 Internal Server Error
,但是当我使用 PostMan 时 API returns 这个 JSON 状态码为 500 的响应。
{
"error": {
"statusCode": 500,
"name": "Error",
"message":"Failed to add object with ID:900 as the object exists",
"stack":"some long message"
}
}
我使用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);
});
我的问题是,当出现 API returns 状态代码为 500 的错误时,如何访问 JSON 响应?
看.onErrorMap()
,给你例外看。由于您可能还需要查看 exchange() 的 body(),因此不要使用 retrieve,而是
.exchange().flatMap((ClientResponse) response -> ....);
正如@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);
});
我还注意到有从 1xx 到 5xx 的几个状态代码,这将使我在不同情况下更容易处理错误
如果您想检索错误详细信息:
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();
和
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;
}
}
并与 ErrorDetails
class 映射错误主体
每个请求变体:
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;
})