You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SSLSocketFactory的HttpsURLConnection抛出UnknownHostException问题

解决Java调用API时的UnknownHostException异常

我尝试调用一个需要上传证书才能访问的API,编写了以下API调用方法建立连接,但运行时抛出java.net.UnknownHostException异常。已确认API地址正确且具备访问权限,证书为开发环境的.crt文件,请求解决该问题。

API调用方法

public static String consumeAPI() {
  String respAPI = "";
  String param = "some_param";
  String user = "user";
  String pswrd = "pass";
  try {
    SSLSocketFactory ssl = createSSLSocketFactory("path_of_cert");
    URL url = new URL("https://api-dir.com.es:8080/api");
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setSSLSocketFactory(ssl);
    conn.setDoOutput(true);
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    conn.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString((user + ":" + pswrd).getBytes(StandardCharsets.UTF_8)));
    conn.setConnectTimeout(APIUtils.TIMEOUT);
    try (OutputStream os = conn.getOutputStream()) {
      os.write(parametros.getBytes(StandardCharsets.UTF_8));
      os.flush();
      if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
          StringBuilder result = new StringBuilder();
          String auxStr;
          while ((auxStr = br.readLine()) != null) {
            result.append(auxStr);
          }
          respAPI = result.toString();
        }
      }
    }
    return respAPI;
  }
  catch(IOException | ClassCastException | IllegalStateException | IllegalArgumentException e) {
    e.printStackTrace();
    return null;
  }
}

加载证书的SSLSocketFactory生成方法

private static SSLSocketFactory createSSLSocketFactory(String certPath) {
  try {
    try (InputStream in =APIUtils.class.getResourceAsStream(certPath)) {
      Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate( in );
      KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
      keyStore.load(null);
      keyStore.setCertificateEntry("certalias", certificate);
      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      trustManagerFactory.init(keyStore);
      SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
      sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
      return sslContext.getSocketFactory();
    }
  }
  catch(CertificateException | KeyStoreException | NoSuchAlgorithmException | IOException | KeyManagementException e) {
    e.printStackTrace();
    return null;
  }
}

错误堆栈信息

java.net.UnknownHostException: api-dir.com.es
        at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:567)
        at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
        at java.base/java.net.Socket.connect(Socket.java:633)
        at java.base/sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:304)
        at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:178)
        at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:532)
        at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:637)
        at java.base/sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:266)
        at java.base/sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:380)
        at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:193)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1242)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1128)
        at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:179)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1430)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1401)
        at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:220)
        at deployment.regional.war//com.ekt.regional.web.api.SomeAPI.consumeAPI(SomeAPI.java:49)

解决方案

UnknownHostException本质是DNS解析失败,和证书加载逻辑无关,按以下步骤排查:

  • 测试域名解析:在运行代码的机器上执行ping api-dir.com.es或nslookup api-dir.com.es,确认是否能解析到IP地址。如果解析失败,检查本地DNS配置,或在hosts文件中手动添加域名与IP的映射。
  • 检查网络代理:如果机器使用代理,确认代理是否允许访问该域名。可尝试关闭代理测试,或在代码中设置代理:
    System.setProperty("https.proxyHost", "你的代理地址");
    System.setProperty("https.proxyPort", "你的代理端口");
    
  • 确认端口可达性:用telnet api-dir.com.es 8080或nc -zv api-dir.com.es 8080测试8080端口是否开放。
  • 修正代码变量错误:调用API的代码中,定义的变量是param,但写入流时用了parametros,需修正为param.getBytes(StandardCharsets.UTF_8),避免后续出现异常。

内容的提问来源于stack exchange,提问作者TimeToCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:14:54