Рубрики
Без рубрики

Обработка ошибок пружинной пластины

Узнайте, как обрабатывать ошибки с помощью RestTemplate Spring

Автор оригинала: baeldung.

1. Обзор

В этом коротком руководстве мы обсудим, как реализовать и внедрить интерфейс ResponseErrorHandler в экземпляр RestTemplate – для изящной обработки ошибок HTTP, возвращаемых удаленными API.

2. Обработка Ошибок по умолчанию

По умолчанию RestTemplate выдаст одно из этих исключений в случае ошибки HTTP:

  1. HttpClientErrorException – в случае HTTP – статуса 4xx
  2. Исключение HttpServerErrorException – в случае состояния HTTP 5xx
  3. UnknownHttpStatusCodeException – в случае неизвестного состояния HTTP

Все эти исключения являются расширениями RestClient Response Exception .

Очевидно, что самая простая стратегия добавления пользовательской обработки ошибок-это обернуть вызов в блок try/catch . Затем мы обрабатываем пойманное исключение так, как считаем нужным.

Однако эта простая стратегия плохо масштабируется по мере увеличения числа удаленных API или вызовов. Было бы более эффективно, если бы мы могли реализовать многоразовый обработчик ошибок для всех наших удаленных вызовов.

3. Реализация ResponseErrorHandler

Итак, класс, реализующий ResponseErrorHandler , будет считывать состояние HTTP из ответа и либо:

  1. Создайте исключение, которое имеет значение для нашего приложения
  2. Просто игнорируйте состояние HTTP и позвольте потоку ответов продолжаться без перерыва

Нам нужно внедрить реализацию ResponseErrorHandler в экземпляр RestTemplate .

Следовательно, мы используем Rest TemplateBuilder для создания шаблона и замены DefaultResponseErrorHandler в потоке ответов.

Итак, давайте сначала реализуем наш RestTemplate ResponseErrorHandler:

@Component
public class RestTemplateResponseErrorHandler 
  implements ResponseErrorHandler {

    @Override
    public boolean hasError(ClientHttpResponse httpResponse) 
      throws IOException {

        return (
          httpResponse.getStatusCode().series() == CLIENT_ERROR 
          || httpResponse.getStatusCode().series() == SERVER_ERROR);
    }

    @Override
    public void handleError(ClientHttpResponse httpResponse) 
      throws IOException {

        if (httpResponse.getStatusCode()
          .series() == HttpStatus.Series.SERVER_ERROR) {
            // handle SERVER_ERROR
        } else if (httpResponse.getStatusCode()
          .series() == HttpStatus.Series.CLIENT_ERROR) {
            // handle CLIENT_ERROR
            if (httpResponse.getStatusCode() == HttpStatus.NOT_FOUND) {
                throw new NotFoundException();
            }
        }
    }
}

Затем мы создаем экземпляр RestTemplate с помощью Rest TemplateBuilder, чтобы представить наш RestTemplateResponseErrorHandler :

@Service
public class BarConsumerService {

    private RestTemplate restTemplate;

    @Autowired
    public BarConsumerService(RestTemplateBuilder restTemplateBuilder) {
        RestTemplate restTemplate = restTemplateBuilder
          .errorHandler(new RestTemplateResponseErrorHandler())
          .build();
    }

    public Bar fetchBarById(String barId) {
        return restTemplate.getForObject("/bars/4242", Bar.class);
    }

}

4. Тестирование Нашей Реализации

Наконец, давайте проверим этот обработчик, издеваясь над сервером и возвращая состояние NOT_FOUND :

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { NotFoundException.class, Bar.class })
@RestClientTest
public class RestTemplateResponseErrorHandlerIntegrationTest {

    @Autowired 
    private MockRestServiceServer server;
 
    @Autowired 
    private RestTemplateBuilder builder;

    @Test(expected = NotFoundException.class)
    public void  givenRemoteApiCall_when404Error_thenThrowNotFound() {
        Assert.assertNotNull(this.builder);
        Assert.assertNotNull(this.server);

        RestTemplate restTemplate = this.builder
          .errorHandler(new RestTemplateResponseErrorHandler())
          .build();

        this.server
          .expect(ExpectedCount.once(), requestTo("/bars/4242"))
          .andExpect(method(HttpMethod.GET))
          .andRespond(withStatus(HttpStatus.NOT_FOUND));

        Bar response = restTemplate 
          .getForObject("/bars/4242", Bar.class);
        this.server.verify();
    }
}

5. Заключение

В этой статье представлено решение для реализации и тестирования пользовательского обработчика ошибок для RestTemplate , который преобразует ошибки HTTP в значимые исключения.

Как всегда, код, представленный в этой статье, доступен на Github .