Эта статья является седьмой статьей на RestTemplate.Адрес доступа к блогу предыдущей статьи выглядит следующим образом:
- Intensive RestTemplate, часть 1. Как использовать его в среде Spring или не Spring
- Интенсивный RestTemplate, часть 2 — переключение различных базовых библиотек классов HTTP-клиентов
- Intensive RestTemplate, часть 3 — подробное объяснение использования запросов GET
- Intensive RestTemplate Часть 4 — Подробное объяснение метода запроса POST
- Интенсивный RestTemplate, часть 5. Подробное объяснение использования DELETE, PUT и других методов запроса
- Intensive RestTemplate, часть 6 — загрузка и загрузка файлов и потоковая загрузка больших файлов
1. Аномальное явление
При использовании RestTemplate для выполнения вызовов службы удаленного интерфейса, когда запрошенная служба ненормальна: тайм-аут, служба не существует и т. д. (статус ответа не 200, а 400, код состояния HTTP 500), будет выдано следующее исключение:

Я смоделировал исключение и изменил правильный адрес службы запросов с «/posts/1» на «/posts/1». Служба не существует, поэтому возникает исключение 404.
@Test
public void testEntity() {
String url = "http://jsonplaceholder.typicode.com/postss/1";
ResponseEntity<String> responseEntity
= restTemplate.getForEntity(url, String.class); //这行抛出异常
//下面两行代码执行不到
HttpStatus statusCode = responseEntity.getStatusCode(); // 获取响应码
System.out.println("HTTP 响应状态:" + statusCode);
}
После возникновения исключения код программы не может быть выполнен, а последующий код не может быть выполнен. В реальном развитии бизнеса иногда мы ожидаем большего результата: независимо от того, истек ли срок службы вашего сервера или служба не существует, мы должны получить окончательный результат запроса (статус результата HTTP-запроса 400, 500), вместо того, чтобы получить исключение. .
Во-вторых, анализ исходного кода — реализация по умолчанию
Прежде всего, хочу сделать вывод: исключения результатов запроса RestTemplate можно настраивать. Прежде чем запускать пользовательскую логику обработки исключений, необходимо взглянуть на реализацию обработки исключений по умолчанию. То есть: почему происходит явление, упомянутое в предыдущем подразделе?
- ResponseErrorHandler — это интерфейс обработчика исключений для результатов запроса RestTemplate.
- Первый метод hasError интерфейса используется для определения того, является ли HttpResponse ненормальным ответом (через код состояния).
- Второй метод handleError интерфейса используется для обработки аномального результата ответа (сегмент кода состояния, отличный от 200).
- DefaultResponseErrorHandler — это реализация ResponseErrorHandler по умолчанию.
Итак, давайте посмотрим, как DefaultResponseErrorHandler обрабатывает ненормальные ответы? Http StatusCode анализируется из HttpResponse.Если код состояния StatusCode имеет значение null, создается исключение UnknownHttpStatusCodeException.

Если StatusCode существует, анализируется серия StatusCode, то есть сегмент кода состояния (кроме 200 сегментов, все остальные являются ненормальными кодами состояния).Правило анализа: StatusCode/100 с округлением в большую сторону.
public enum Series {
INFORMATIONAL(1), // 1xx/100
SUCCESSFUL(2), // 2xx/100
REDIRECTION(3), // 3xx/100
CLIENT_ERROR(4), // 4xx/100 ,客户端异常
SERVER_ERROR(5); // 5xx/100 ,服务端异常
}
Дальнейшая обработка исключений на стороне клиента и исключений на стороне сервера выполняется путем создания исключения HttpClientErrorException. Это причина исключения в первом подразделе

3. Настраиваемая обработка исключений RestTemplate
Итак, нам нужно реализовать собственные исключения, просто реализовать интерфейс ResponseErrorHandler.
public class MyRestErrorHandler implements ResponseErrorHandler {
/**
* 判断返回结果response是否是异常结果
* 主要是去检查response 的HTTP Status
* 仿造DefaultResponseErrorHandler实现即可
*/
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
int rawStatusCode = response.getRawStatusCode();
HttpStatus statusCode = HttpStatus.resolve(rawStatusCode);
return (statusCode != null ? statusCode.isError(): hasError(rawStatusCode));
}
protected boolean hasError(int unknownStatusCode) {
HttpStatus.Series series = HttpStatus.Series.resolve(unknownStatusCode);
return (series == HttpStatus.Series.CLIENT_ERROR || series == HttpStatus.Series.SERVER_ERROR);
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
// 里面可以实现你自己遇到了Error进行合理的处理
//TODO 将接口请求的异常信息持久化
}
}
Зарегистрируйте MyRestErrorHandler при создании экземпляра RestTemplate. Ссылаться на:«Intensive RestTemplate, часть 1 — как использовать его в среде Spring или Non-Spring»а также«Прекрасный разговор о RestTemplate, часть 2 — переключение различных базовых библиотек HTTP-клиентских классов»воплощать в жизнь

В это время выполните пример кода в первом подразделе, и никаких исключений не будет. Вместо этого получите результат HTTP Status 404. Основываясь на этом результате, мы можем продолжить код в программе.

Добро пожаловать, чтобы обратить внимание на мой блог, в нем много прекрасных коллекций
- Эта статья воспроизводится с указанием источника (должна быть ссылка, а не только текст):Блог Адетокунбо.
Если вы считаете это полезным, пожалуйста, поставьте лайк и поделитесь! Ваша поддержка - моя неиссякаемая творческая мотивация!. Кроме того, автор недавно выпустил следующий прекрасный контент, с нетерпением жду вашего внимания.