У меня есть служба отдыха в аннотированном классе RestController.
@ResponseStatus(HttpStatus.NO_CONTENT)
@PostMapping(path = SUBMIT_OPENFORM_PATH, consumes = APPLICATION_JSON_VALUE)
public Mono<Void> submitForm(@RequestBody Form form) {
return service.submitForm(form);
}
и GlobalExceptionHandler задают настраиваемое сообщение в EntityResponse при возникновении ошибки:
@ExceptionHandler(ResourceNotFoundException.class)
private ResponseEntity<Error> handleResourceNotFoundException(ResourceNotFoundException e) {
log.warn("Unknown resource: {}", e.getMessage());
return ErrorResponseEntity.fromError(
ResourceNotFound.builder()
.errorReason(e.getMessage())
.build()
);
}
Затем У меня есть такой метод как у клиента этой службы. Я могу использовать RestTemplate или WebClient для вызова службы:
public void proxyOpenformSubmission(String payload) throws Exception {
try {
callFormSubmitWithWebClient(payload, token);
} catch (Exception e) {
throw(e);
}
}
Мне нужно получить точное сообщение об исключении, установленное в ExceptionHandler, при ответе или что-то еще при возникновении ошибки. Я получаю код HttpStatus, но мне также нужно получить настраиваемое сообщение об ошибке. Я проверял ClientResponse, сообщения не оказалось. Что я делаю не так? Я пытаюсь установить фильтр в WebClient, чтобы получить ответ и создать собственное исключение на основе ответа:
private void callOpenformSubmitWithWebClient(String formPayload, String token) throws Exception {
WebClient webClient = WebClient.builder()
.baseUrl(submitFormUri)
.defaultHeader(HttpHeaders.CONTENT_TYPE, "application/json")
.filter(errorHandlingFilter())
.build();
webClient.post()
.accept(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(formPayload))
.headers(headers -> headers.setBearerAuth(token))
.retrieve()
.bodyToMono(String.class)
.block();
}
Фильтр:
public static ExchangeFilterFunction errorHandlingFilter() {
return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
if(clientResponse.statusCode() != null && (clientResponse.statusCode().is5xxServerError() || clientResponse.statusCode().is4xxClientError()) ) {
//return clientResponse.createException().flatMap( Mono::error );
return clientResponse.bodyToMono(String.class)
.flatMap(errorBody -> Mono.error(new CustomWebClientResponseException(errorBody , clientResponse.statusCode())));
} else {
return Mono.just(clientResponse);
}
});
}
Это работает с WebClient, но если Я пытаюсь вызвать это с помощью RestTemplate, тип содержимого в заголовках ответа равен 0, и поэтому тело будет нулевым. Единственное, что я бы увидел, используя RestTemplate вместо WebClient, - это HttpStatus code 400 и его фразу, но не мое собственное сообщение. Неважно, использую ли я postForEntity, exchange ... Он всегда возвращает размер содержимого 0 с RestTemplate.