1. Обзор
Служба RESTful может выйти из строя по ряду причин. В этом руководстве мы рассмотрим, как получить исходное сообщение от клиента Feign , если интегрированная служба REST выдает ошибку.
2. Притвориться клиентом
Feign — это подключаемый и декларативный клиент веб-службы, упрощающий написание клиентов веб-службы. В дополнение к аннотациям Feign он также поддерживает JAX-RS и поддерживает кодировщики и декодеры для обеспечения большей настройки .
3. Получение сообщения от ErrorDecoder
При возникновении ошибок клиент Feign подавляет исходное сообщение, и для его извлечения нам требуется написать собственный ErrorDecoder
. При отсутствии такой настройки мы получим следующую ошибку:
feign.FeignException$NotFound: [404] during [POST] to [http://localhost:8080/upload-error-1] [UploadClient#fileUploadError(MultipartFile)]: [{"timestamp":"2022-02-18T13:25:22.083+00:00","status":404,"error":"Not Found","path":"/upload-error-1"}]
at feign.FeignException.clientErrorStatus(FeignException.java:219) ~[feign-core-11.7.jar:na]
at feign.FeignException.errorStatus(FeignException.java:194) ~[feign-core-11.7.jar:na]
Чтобы обработать эту ошибку, мы создадим простой Java-бин ExceptionMessage
, представляющий сообщение об ошибке:
public class ExceptionMessage {
private String timestamp;
private int status;
private String error;
private String message;
private String path;
// standard getters and setters
}
Давайте извлечем исходное сообщение, извлекая его в нашей настраиваемой реализации ErrorDecoder
:
public class RetreiveMessageErrorDecoder implements ErrorDecoder {
private ErrorDecoder errorDecoder = new Default();
@Override
public Exception decode(String methodKey, Response response) {
ExceptionMessage message = null;
try (InputStream bodyIs = response.body()
.asInputStream()) {
ObjectMapper mapper = new ObjectMapper();
message = mapper.readValue(bodyIs, ExceptionMessage.class);
} catch (IOException e) {
return new Exception(e.getMessage());
}
switch (response.status()) {
case 400:
return new BadRequestException(message.getMessage() != null ? message.getMessage() : "Bad Request");
case 404:
return new NotFoundException(message.getMessage() != null ? message.getMessage() : "Not found");
default:
return errorDecoder.decode(methodKey, response);
}
}
}
В нашей реализации мы добавили логику, основанную на возможных ошибках, и, следовательно, мы можем настроить их в соответствии с нашими требованиями. В случае нашего блока переключателей по умолчанию
мы используем реализацию ErrorDecoder по умолчанию.
Реализация по умолчанию
декодирует ответ HTTP, когда статус не находится в диапазоне 2xx. Когда throwable
является retryable
, он должен быть подтипом RetryableException,
и мы должны по возможности вызывать исключения для конкретного приложения.
Чтобы настроить наш настроенный ErrorDecoder
, мы добавим нашу реализацию в виде bean-компонента в конфигурацию Feign:
@Bean
public ErrorDecoder errorDecoder() {
return new RetreiveMessageErrorDecoder();
}
Теперь давайте посмотрим на исключение с исходным сообщением:
com.foreach.cloud.openfeign.exception.NotFoundException: Page Not found
at com.foreach.cloud.openfeign.fileupload.config.RetreiveMessageErrorDecoder.decode(RetreiveMessageErrorDecoder.java:30) ~[classes/:na]
at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:96) ~[feign-core-11.7.jar:na]
4. Вывод
В этой статье мы продемонстрировали, как настроить ErrorDecoder
, чтобы мы могли перехватывать ошибки Feign для извлечения исходного сообщения.
Как обычно, все примеры кода, использованные в этом руководстве, доступны на GitHub .