J'utilise le client Web printan Webflux, comme ceci:
WebClient.create()
.post()
.uri(url)
.syncBody(body)
.accept(MediaType.APPLICATION_JSON)
.headers(headers)
.exchange()
.flatMap(clientResponse -> clientResponse.bodyToMono(tClass));
Cela fonctionne bien. Je souhaite maintenant gérer l’erreur du service Web que j’appelle (erreur interne Ex 500). Normalement, je voudrais ajouter un doOnError sur le "flux" et isu le Throwable pour tester le code d'état,
Mais mon problème est que je veux obtenir le corps fourni par le service Web, car il me fournit un message que je voudrais utiliser.
Je cherche à faire le flatMap quoi qu'il arrive, et à tester moi-même le code d'état pour désérialiser ou non le corps.
Notez que, au moment d'écrire cela, les erreurs 5xx n'entraînent plus d'exception de la couche Netty sous-jacente. Voir https://github.com/spring-projects/spring-framework/commit/b0ab84657b712aac59951420f4e9d696c3d84ba2
Je fais quelque chose comme ça:
Mono<ClientResponse> responseMono = requestSpec.exchange()
.doOnNext(response -> {
HttpStatus httpStatus = response.statusCode();
if (httpStatus.is4xxClientError() || httpStatus.is5xxServerError()) {
throw new WebClientException(
"ClientResponse has erroneous status code: " + httpStatus.value() +
" " + httpStatus.getReasonPhrase());
}
});
et alors:
responseMono.subscribe(v -> { }, ex -> processError(ex));
Nous avons enfin compris ce qui se passait: Par défaut, le httpclient (HttpClientRequest) de Netty est configuré pour échouer en cas d’erreur de serveur (réponse 5XX) et non d’erreur de client (4XX), raison pour laquelle il émettait toujours une exception .
Ce que nous avons fait, c’est d’étendre AbstractClientHttpRequest et ClientHttpConnector pour configurer le httpclient de la manière dont il veut et lorsque nous appelons le WebClient, nous utilisons notre ClientHttpConnector personnalisé:
WebClient.builder().clientConnector(new CommonsReactorClientHttpConnector()).build();
Tu pourrais aussi faire ça
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);
});
Lisez cet article pour plus d'exemples link , je l'ai trouvé utile lorsque j'ai rencontré un problème similaire avec la gestion des erreurs