在 Spring Boot 中使用 Web Client Mono 获取 API 响应错误消息
Posted
技术标签:
【中文标题】在 Spring Boot 中使用 Web Client Mono 获取 API 响应错误消息【英文标题】:Get API response error message using Web Client Mono in Spring Boot 【发布时间】:2018-09-04 05:56:15 【问题描述】:我正在使用 webflux Mono(在 Spring Boot 5 中)来使用外部 API。当 API 响应状态码为 200 时,我能够很好地获取数据,但是当 API 返回错误时,我无法从 API 中检索错误消息。 Spring webclient 错误处理程序始终将消息显示为
ClientResponse has erroneous status code: 500 Internal Server Error
,但是当我使用 PostMan 时,API 返回此 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 返回状态码为 500 的错误时,我如何才能访问 JSON 响应?
【问题讨论】:
【参考方案1】:如果要检索错误详细信息:
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
类映射错误正文
每个请求的变体:
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;
)
【讨论】:
如何捕捉抛出的异常? 什么是 ErrorDetails 类? @2dsharp 你可以用 AbstractErrorWebExceptionHandler 捕获你的异常【参考方案2】:正如@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 的状态代码,这将使我在不同情况下更容易处理错误
【讨论】:
如果我的 Response 类不是 String 怎么办?这还能用吗? @Rocky4Ever 是的,您只需更改预期的类型,它应该可以工作。顺便说一下,我不确定它是否适用于原始数据类型exchange()
已弃用,但用exchangeToMono()
替换它和flatMap()
似乎可行。【参考方案3】:
查看.onErrorMap()
,它为您提供了查看的例外情况。由于您可能还需要exchange() 的body() 来查看,所以不要使用retrieve,而是
.exchange().flatMap((ClientResponse) response -> ....);
【讨论】:
以上是关于在 Spring Boot 中使用 Web Client Mono 获取 API 响应错误消息的主要内容,如果未能解决你的问题,请参考以下文章
springcloud启动web模块报错spring-boot-maven-plugin:2.2.1.RELEASE:run (default-cli) on project da-web(示例代(代