1. Обзор
В этом руководстве мы рассмотрим, как использовать Java HttpClient для подключения к URL-адресам HTTPS. Мы также узнаем, как использовать клиент с URL-адресами, не имеющими действительного сертификата SSL.
В старых версиях Java для подключения к серверу мы предпочитали использовать такие библиотеки, как Apache HTTPClient и OkHttp. В Java 11 в JDK была добавлена улучшенная библиотека HttpClient . Давайте рассмотрим, как использовать его для вызова службы через SSL.
2. Вызов URL-адреса HTTPS с помощью Java HttpClient
Мы будем использовать тестовые примеры для запуска клиентского кода. В целях тестирования мы будем использовать существующий URL-адрес, работающий по протоколу HTTPS.
Давайте напишем код для настройки клиента и вызова службы:
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://www.google.com/"))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
Здесь мы сначала создали клиента, используя метод HttpClient.newHttpClient()
. Затем мы создали запрос и установили URL-адрес сервиса, который мы собираемся использовать. Наконец, мы отправили запрос с помощью метода HttpClient.send()
и получили ответ — объект HttpResponse
, содержащий тело ответа в виде строки.
Когда мы поместим приведенный выше код в тестовый пример и выполним приведенное ниже утверждение, мы увидим, что он проходит:
assertEquals(200, response.statusCode());
3. Вызов недействительного URL-адреса HTTPS
Теперь давайте изменим URL-адрес на другой, у которого нет действительного сертификата SSL. Мы можем сделать это, изменив объект запроса:
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://www.testingmcafeesites.com/"))
.build();
Когда мы снова запускаем тест, мы получаем следующую ошибку:
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching www.testingmcafeesites.com found.
at java.base/sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:212)
at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:103)
Это связано с тем, что URL-адрес не имеет действительного сертификата SSL.
4. Обход проверки SSL-сертификата
Чтобы устранить ошибку, которую мы получили выше, давайте рассмотрим решение для обхода проверки сертификата SSL.
В Apache HttpClient мы могли бы изменить клиент, чтобы обойти проверку сертификата . Однако мы не можем сделать это с помощью Java HttpClient. Нам придется полагаться на внесение изменений в JVM, чтобы отключить проверку имени хоста.
Один из способов сделать это — импортировать сертификат веб-сайта в хранилище ключей Java . Это обычная практика, и это хороший вариант, если есть небольшое количество внутренних надежных веб-сайтов.
Однако это может стать утомительным, если имеется большое количество веб-сайтов или слишком много сред для управления. В этом случае мы можем использовать свойство jdk.internal.httpclient.disableHostnameVerification
, чтобы отключить проверку имени хоста.
Мы можем установить это свойство при запуске приложения в качестве аргумента командной строки :
java -Djdk.internal.httpclient.disableHostnameVerification=true -jar target/java-httpclient-ssl-0.0.1-SNAPSHOT.jar
Кроме того, мы можем программно установить это свойство перед созданием нашего клиента :
Properties props = System.getProperties();
props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());
HttpClient httpClient = HttpClient.newHttpClient();
Когда мы запустим тест сейчас, мы увидим, что он проходит.
Следует отметить, что изменение свойства будет означать, что проверка сертификата будет отключена для всех запросов. Это может быть нежелательно, особенно в производстве. Однако обычно это свойство вводится в непроизводственных средах.
5. Можем ли мы использовать Java HttpClient с Spring?
Spring предоставляет два популярных интерфейса для выполнения HTTP-запросов:
RestTemplate
для синхронных запросовWebClient
для синхронных и асинхронных запросов
Оба могут использоваться вместе с популярными HTTP-клиентами, такими как Apache HttpClient, OkHttp и старый HttpURLConnection
. Однако мы не можем подключить Java HttpClient к этим двум интерфейсам . Это скорее рассматривается как альтернатива им.
Мы можем использовать Java HttpClient для выполнения синхронных и асинхронных запросов, преобразования запросов и ответов, добавления тайм-аутов и т. д. Таким образом, его можно использовать напрямую, без использования интерфейсов Spring.
6. Заключение
В этой статье мы рассмотрели, как использовать HTTP-клиент Java для подключения к серверу, для которого требуется SSL. Мы также рассмотрели способы использования клиента с URL-адресами, не имеющими действительного сертификата.
Как всегда, код этих примеров доступен на GitHub .