java - 使用 Maven 和 Java 11 通过 SSL 进行 HTTP Get 请求

标签 java maven ssl http-get

我正在尝试使用 SSL 发出 HTTP get 请求,以检查与远程服务器的连接是否正常工作,我在互联网上找到了几个示例,但没有一个完全解析,似乎 java 正在不断变化、弃用和删除旧的类和方法。

这是我可以获得的最大解析代码(有些行仍然无法解析):

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.SSLContext;
import org.apache.http.ssl.SSLContexts;
//import org.apache.http.conn.ssl.SSLContexts;  


public class SSLContextLoader {


   public static SSLContext initSSLContext () {
      String clientKeyStorePath = ConfigManager.GetInstance().GetKeyStorePath();
      String trustStorePath = ConfigManager.GetInstance().GetTrustStorePath();
      String clientKeyStorePassword = ConfigManager.GetInstance().GetKeyStorePassword();
      String trustStorePassword = ConfigManager.GetInstance().GetTrustStorePassword();
      String keyPassword = clientKeyStorePassword;
      try {
         final KeyStore clientKeystore = KeyStore.getInstance("JKS");
         clientKeystore.load(new FileInputStream(clientKeyStorePath), clientKeyStorePassword.toCharArray());
         final KeyStore trustStore = KeyStore.getInstance("JKS");
         trustStore.load(new FileInputStream(trustStorePath), trustStorePassword.toCharArray());

         final SSLContext sslContext = SSLContexts.custom()
            .loadTrustMaterial(trustStore, null)
            .loadKeyMaterial(clientKeystore, keyPassword.toCharArray())
            .build();

         return sslContext;
      } catch (KeyStoreException e) {
         e.printStackTrace();
      } catch (CertificateException e) {
         e.printStackTrace();
      } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (UnrecoverableKeyException e) {
         e.printStackTrace();
      } catch (KeyManagementException e) {
         e.printStackTrace();
      }
     return null;
   }
}


import java.io.IOException;
import java.net.URI;
import java.net.http.HttpRequest;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;


public class GetRequest {
       
   private final static String ENDPOINT_URL = "https://www.google.com/";

   public void sendSSLRequest() {

      final SSLContext sslContext = SSLContextLoader.initSSLContext();

      final HttpClientBuilder clientbuilder = HttpClients.custom().setSslcontext(sslContext);
      final HttpClient client = clientbuilder.build();
                                   
      //final HttpGet request = new HttpGet(ENDPOINT_URL);
      // HttpClient httpClient = HttpClient.newHttpClient();
    
      HttpRequest request = HttpRequest.newBuilder()
          .uri(URI.create("https://www.google.com/"))
          .build();

      //HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); // cannot find symbols httpClient and BodyHandlers

      try {
         // the following code needs a cast to (HttpUriRequest) to parse : 
         client.execute(request);   // expecting (HttpUriRequest) and we have HttpRequest  
      } catch (final IOException e) {
         //do some exception handling...
      }
   }

} 

httpClient.send 未解析,因为未找到 httpClient。

还有 client.execute(request);未解析,因为构建器返回 HttpRequest 并且执行方法需要 HttpUriRequest,它是一个子类。

发送和执行是发送请求的两种选择(可能在不同版本的库中工作),并且都不解析。

这是我的 apache 库的两个 Maven 依赖项:

 <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.3.5</version>
         <type>jar</type>
     </dependency>
   <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
        <version>4.4.8</version>
    </dependency>

最佳答案

您需要生成与其接口(interface)不同的 HttpUriRequest,因此您必须使用其实现类来创建其对象并将其传递给执行方法。还 HttpClientBuilder 类型中的方法 setSslcontext(SSLContext) 已弃用,因此您应该使用 SSLConnectionSocketFactory。

没有代理

public void sendSSLRequest() {
    final SSLContext sslContext = SSLContextLoader.initSSLContext();
    final SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    final CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(csf).build();
    HttpUriRequest request = new HttpGet(URI.create("https://www.google.com/"));
    try {
        client.execute(request);
    } catch (final IOException e) {
        // do some exception handling...
    }
}

使用代理且无需身份验证

public void sendSSLRequest() {
    HttpHost proxy = new HttpHost("ip address", 8080);
    DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);

    final SSLContext sslContext = SSLContextLoader.initSSLContext();
    final SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    final CloseableHttpClient client =
            HttpClients.custom().setSSLSocketFactory(csf).setRoutePlanner(routePlanner).build();
    HttpUriRequest request = new HttpGet(URI.create("https://www.google.com/"));
    try {
        client.execute(request);
    } catch (final IOException e) {
        // do some exception handling...
    }
}

使用带有身份验证的代理

public void sendSSLRequest() {
    HttpHost proxy = new HttpHost("ip address", 8080);
    DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);

    // Client credentials
    CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(new AuthScope(proxy),
            new UsernamePasswordCredentials("username_admin", "secret_password"));

    // Create AuthCache instance
    AuthCache authCache = new BasicAuthCache();

    BasicScheme basicAuth = new BasicScheme();
    authCache.put(proxy, basicAuth);
    HttpClientContext context = HttpClientContext.create();
    context.setCredentialsProvider(credentialsProvider);
    context.setAuthCache(authCache);

    final SSLContext sslContext = SSLContextLoader.initSSLContext();
    final SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    final CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(csf).setRoutePlanner(routePlanner)
            .setDefaultCredentialsProvider(credentialsProvider).build();
    HttpUriRequest request = new HttpGet(URI.create("https://www.google.com/"));
    try {
        client.execute(request, context);
    } catch (final IOException e) {
        // do some exception handling...
    }
}

关于java - 使用 Maven 和 Java 11 通过 SSL 进行 HTTP Get 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73933042/

相关文章:

java - 如果Java中HashMap键相等,如何取2个最大值

maven - 运行 jar 文件时 spring boot 中的 java.lang.ClassNotFoundException - 添加了库

java - 如何为 ehcache 构建单个 jar?

java - 找不到 apache commons 类 - 添加 jar 后

php - Laravel 5.2.31 Socialite 证书 ssl 错误

php - 带有 .p12 SSL 证书的curl/soap 请求

docker - Docker 和 Letsencrypt 证书再次出现 Keycloak 错误

windows-7 - JRE 6 和 7 并存,默认为 JRE 6 (Win 7)

java - Primefaces 错误消息在提交时不会消失

Java GridBagLayout 和 JPanel 错误 : cannot add to layout: constraint must be a string (or null)