Java HttpClient With SSL – 带SSL的Java HttpClient

最后修改: 2022年 5月 8日

1. Overview


In this tutorial, we’ll explore how to use the Java HttpClient to connect to HTTPS URLs. We’ll also learn how to use the client with URLs that don’t have a valid SSL certificate.

在本教程中,我们将探讨如何使用Java HttpClient连接到HTTPS URLs。我们还将学习如何在没有有效SSL证书的URL上使用该客户端。

In older versions of Java, we preferred to use libraries like Apache HTTPClient and OkHttp to connect to a server. In Java 11, an improved HttpClient library was added to the JDK. Let’s explore how to use it to call a service over SSL.

在旧版本的Java中,我们倾向于使用Apache HTTPClient和OkHttp等库来连接到服务器。在Java 11中,一个改进的HttpClient库被添加到JDK中。让我们探讨一下如何使用它来通过SSL调用服务。

2. Calling an HTTPS URL Using the Java HttpClient

2.使用Java HttpClient调用一个HTTPS URL

We’ll use test cases to run the client code. For testing purposes, we’ll use an existing URL that runs on HTTPS.


Let’s write code to set up the client and call the service:


HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()

HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

Here, we first created a client using the HttpClient.newHttpClient() method. Then, we created a request and set the URL of the service we’re going to hit. Finally, we sent the request using the HttpClient.send() method and collected the response – a HttpResponse object containing the response body as a String.

在这里,我们首先使用HttpClient.newHttpClient() 方法创建了一个客户端。然后,我们创建了一个请求,并设置了我们要打的服务的URL。最后,我们使用HttpClient.send()方法发送请求,并收集响应–一个HttpResponse对象,包含作为字符串的响应体。

When we put the above code in a test case and perform the below assertion, we’ll observe that it passes:


assertEquals(200, response.statusCode());

3. Calling an Invalid HTTPS URL

3.调用一个无效的HTTPS URL

Now, let’s change the URL to another one that doesn’t have a valid SSL certificate. We can do so by changing the request object:


HttpRequest request = HttpRequest.newBuilder()
  .uri(new URI(""))

When we run the test again, we get the below error:


Caused by: No subject alternative DNS name matching found.
  at java.base/
  at java.base/

This is because the URL doesn’t have a valid SSL certificate.


4. Bypassing SSL Certificate Verification


To resolve the error we got above, let’s look at a solution to bypass SSL certificate verification.


In Apache HttpClient, we could modify the client to bypass certificate verification. However, we can’t do that with the Java HttpClient. We’ll have to rely on making changes to the JVM to disable hostname verification.

在Apache HttpClient中,我们可以修改客户端以绕过证书验证。然而,在Java HttpClient中,我们不能这样做。我们将不得不依靠对JVM的修改来禁用主机名验证。

One way to do this is to import the website’s certificate into the Java KeyStore. This is a common practice and is a good option if there are a small number of internal, trusted websites.

一种方法是将网站的证书导入到Java KeyStore中。这是一种常见的做法,如果有少量的内部受信任的网站,这是一个不错的选择。

However, this can become tiresome if there are a large number of websites or too many environments to manage. In this case, we can use the property jdk.internal.httpclient.disableHostnameVerification to disable hostname verification.


We can set this property when running the application as a command-line argument:


java -Djdk.internal.httpclient.disableHostnameVerification=true -jar target/java-httpclient-ssl-0.0.1-SNAPSHOT.jar

Alternatively, we can programmatically set this property before creating our client:


Properties props = System.getProperties();
props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());

HttpClient httpClient = HttpClient.newHttpClient();

When we run the test now, we’ll see that it passes.


We should note that changing the property would mean that certificate verification is disabled for all requests. This may not be desirable, especially in production. However, it’s common to introduce this property in non-production environments.

我们应该注意,改变该属性将意味着对所有请求禁用证书验证。 这可能不可取,特别是在生产环境中。然而,在非生产环境中引入该属性是很常见的。

5. Can We Use Java HttpClient With Spring?

5.我们可以在Spring中使用Java HttpClient吗?

Spring provides two popular interfaces to make HTTP requests:


  • RestTemplate for synchronous requests
  • WebClient for synchronous and asynchronous requests

Both can be used along with popular HTTP clients such as Apache HttpClient, OkHttp, and the old HttpURLConnection. However, we can’t plug Java HttpClient into these two interfaces. It’s rather seen as an alternative to them.

两者都可以与流行的HTTP客户端一起使用,如Apache HttpClient、OkHttp和旧的HttpURLConnection。然而,我们不能将Java HttpClient插入这两个接口它反而被看作是它们的替代品。

We can use Java HttpClient to make synchronous and asynchronous requests, convert requests and responses, add timeouts, etc. Therefore, it can be utilized directly without needing Spring’s interfaces.

我们可以使用Java HttpClient来进行同步和异步请求,转换请求和响应,添加超时等等。因此,可以直接利用它而不需要Spring的接口。

6. Conclusion


In this article, we explored how to use the Java HTTP Client to connect to a server that requires SSL. We also looked at ways to use the client with URLs that don’t have a valid certificate.

在这篇文章中,我们探讨了如何使用Java HTTP客户端连接到一个需要SSL的服务器。我们还研究了对没有有效证书的URL使用客户端的方法。

As always, the code for these examples is available over on GitHub.