1. 개요
이 사용방법(예제)에서는 Java HttpClient를 사용하여 HTTPS URL에 연결하는 방법을 살펴봅니다. 유효한 SSL 인증서가 없는 URL로 클라이언트를 사용하는 방법도 알아봅니다.
이전 버전의 Java에서는 Apache HTTPClient 및 OkHttp와 같은 라이브러리를 사용하여 서버에 연결하는 것을 선호했습니다. Java 11에서는 개선된 HttpClient 라이브러리 가 JDK에 추가되었습니다. 이를 사용하여 SSL을 통해 서비스를 호출하는 방법을 살펴보겠습니다.
2. Java HttpClient를 사용하여 HTTPS URL 호출
테스트 케이스를 사용하여 클라이언트 코드를 실행합니다. 테스트 목적으로 HTTPS에서 실행되는 기존 URL을 사용합니다.
클라이언트를 설정하고 서비스를 호출하는 코드를 작성해 보겠습니다.
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() 메서드 를 사용하여 요청을 보내고 응답을 수집했습니다 . Response body을 문자열 로 포함하는 HttpResponse 개체입니다.
위의 코드를 테스트 케이스에 넣고 아래 어설션을 수행하면 통과하는 것을 관찰할 수 있습니다.
assertEquals(200, response.statusCode());
3. 유효하지 않은 HTTPS URL 호출
이제 URL을 유효한 SSL 인증서가 없는 다른 URL로 변경해 보겠습니다. 요청 객체를 변경하면 됩니다.
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 KeyStore로 가져오는 것 입니다. 이것은 일반적인 관행이며 적은 수의 신뢰할 수 있는 내부 웹사이트가 있는 경우 좋은 옵션입니다.
그러나 관리할 웹 사이트가 많거나 환경이 너무 많은 경우에는 번거로울 수 있습니다. 이 경우 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. Spring과 함께 Java HttpClient를 사용할 수 있습니까?
Spring은 HTTP 요청을 만들기 위해 널리 사용되는 두 가지 인터페이스를 제공합니다.
- 동기식 요청을 위한 RestTemplate
- 동기 및 비동기 요청을 위한 WebClient
둘 다 Apache HttpClient, OkHttp 및 이전 HttpURLConnection 과 같은 널리 사용되는 HTTP 클라이언트와 함께 사용할 수 있습니다 . 그러나 Java HttpClient를 이 두 인터페이스에 연결할 수 없습니다 . 오히려 그들에 대한 대안으로 여겨진다.
Java HttpClient를 사용하여 동기 및 비동기 요청, 요청 및 응답 변환, 시간 초과 추가 등을 수행할 수 있습니다. 따라서 Spring의 인터페이스 없이 직접 활용할 수 있습니다.
6. 결론
이 기사에서는 Java HTTP 클라이언트를 사용하여 SSL이 필요한 서버에 연결하는 방법을 살펴보았습니다. 또한 유효한 인증서가 없는 URL로 클라이언트를 사용하는 방법도 살펴보았습니다.
항상 그렇듯이 이러한 예제의 코드는 GitHub 에서 사용할 수 있습니다 .