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

使用HttpClient 4.5.5调用SOAP Web Service遇SSL证书匹配错误求助

嘿,这个问题我之前在对接内部SOAP服务的时候也碰到过,核心原因就是SSL证书的主机名校验不通过,我给你梳理下原因和几种可行的解决办法:

问题根源

你通过IP地址10.xx.xx.xx访问目标SOAP服务,但对方服务器的SSL证书里,**主题备用名称(SAN)**只配置了*.domain.vn和domain.vn,并没有包含你使用的这个IP地址。而HttpClient 4.5.5默认会严格校验请求的主机名(或IP)是否和证书里的SAN/CN匹配,所以直接抛出了SSLPeerUnverifiedException。

解决方案(按安全性从高到低排序)

1. 改用证书匹配的域名访问(最推荐)

如果你的网络环境允许,直接把请求URL换成domain.vn或者对应的子域名(比如soap.domain.vn),而不是用IP。这样证书的主机名校验会自动通过,不需要修改任何代码,这是最合规、最安全的做法。

2. 修改本地hosts文件映射(测试环境优选)

如果因为网络限制只能用IP访问,但又不想跳过SSL校验,可以修改本地hosts文件,把IP映射到证书里的域名:

  • Windows系统:打开C:\Windows\System32\drivers\etc\hosts(需要管理员权限)
  • Linux/macOS系统:编辑/etc/hosts
  • 添加一行:10.xx.xx.xx your-service.domain.vn
  • 之后用your-service.domain.vn作为请求URL,本地会直接解析到目标IP,同时证书校验能匹配域名,完美解决问题。

3. 自定义HttpClient跳过主机名验证(仅测试/内部环境)

如果以上两种方式都不可行,只能临时跳过主机名校验(注意:生产环境绝对禁止这种操作,会暴露在SSL中间人攻击的风险下),可以修改你的HttpClient初始化代码:

static String callApi(String url, String requestXml) {
    String responseXml = "";
    CloseableHttpClient httpClient = null;
    HttpPost httpPost;
    try {
        // 构建跳过主机名验证的SSL上下文
        SSLContext sslContext = SSLContexts.createDefault();
        // 自定义主机名验证器,始终返回验证通过
        X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
            @Override
            public void verify(String host, SSLSocket ssl) throws IOException {}
            
            @Override
            public void verify(String host, X509Certificate cert) throws SSLException {}
            
            @Override
            public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {}
            
            @Override
            public boolean verify(String host, SSLSession session) {
                return true;
            }
        };
        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
                sslContext, hostnameVerifier);
        
        // 创建自定义HttpClient实例
        httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslSocketFactory)
                .build();
        
        httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "text/xml; charset=utf-8");
        httpPost.setHeader("x-ibm-client-id", Config.csp.validKey);
        StringEntity entity = new StringEntity(requestXml, "UTF-8");
        httpPost.setEntity(entity);
        
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity responseEntity = response.getEntity();
        responseXml = EntityUtils.toString(responseEntity, "UTF-8");
    } catch (Exception ex) {
        log.error("调用SOAP API失败", ex);
    } finally {
        try {
            if (httpClient != null) httpClient.close();
        } catch (Exception ex) {
            log.error("关闭HttpClient失败", ex);
        }
    }
    return responseXml;
}

额外提一句:如果目标服务用的是自签名证书,你可能还需要添加信任所有证书的TrustManager,不过同样仅限测试环境使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:57:36