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

使用WebServiceTemplate调用外部服务时遇SSLHandshake错误求助

解决WebServiceTemplate调用时的SSL证书SAN不匹配问题

老哥,这个问题我太熟了!从你贴的错误日志里能一眼看到核心问题:

java.security.cert.CertificateException: No subject alternative DNS name matching www.test-test.com found.

简单来说,你调用的www.test-test.com这个域名,不在目标服务SSL证书的**主题备用名称(Subject Alternative Name,SAN)**列表里——要么是证书里的域名和你实际调用的不一样(比如证书里是不带www的test-test.com),要么就是服务方的证书压根没把这个域名加进去。

下面分场景给你解决方案:

一、生产环境:规范解决(必选)

这是正经生产环境该用的方法,别搞歪门邪道:

  • 先找服务方确认他们的SSL证书里有没有www.test-test.com这个域名的SAN记录,如果没有,让他们更新证书;
  • 如果证书里的域名是不带www的test-test.com,直接把你代码里的wsdlUrl改成https://test-test.com/xxx,保证调用域名和证书上的完全一致就行。

二、开发/测试环境:临时绕开(仅限测试!)

要是开发测试阶段不想被证书卡脖子,想快速跑通代码,可以临时跳过SSL证书校验,但生产绝对不能用!步骤如下:

  1. 先写个工具类,用来创建信任所有证书的SSL上下文:
import javax.net.ssl.*;
import java.security.cert.X509Certificate;

public class SslSkipUtils {
    public static SSLContext createTrustAllSslContext() throws Exception {
        // 自定义TrustManager,信任所有证书
        X509TrustManager trustAllManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) {}
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) {}
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, new TrustManager[]{trustAllManager}, new java.security.SecureRandom());
        return sslContext;
    }
}
  1. 修改你的WebServiceTemplate配置,把自定义的SSL连接工厂加上:
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("wsdl");
webServiceTemplate.setDefaultUri(wsdlUrl);
webServiceTemplate.setMarshaller(marshaller);
webServiceTemplate.setUnmarshaller(marshaller);

// 加入自定义SSL配置,跳过证书和主机名校验
try {
    SSLContext sslContext = SslSkipUtils.createTrustAllSslContext();
    HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender();
    messageSender.setSslContext(sslContext);
    // 同时忽略主机名匹配检查
    messageSender.setHostnameVerifier((hostname, session) -> true);
    webServiceTemplate.setMessageSender(messageSender);
} catch (Exception e) {
    e.printStackTrace();
}

JAXBElement<MyClass> res = (JAXBElement<MyClass>) webServiceTemplate.marshalSendAndReceive(wsdlUrl, xClass);

⚠️ 再次提醒:这种方法等于完全放弃SSL的安全校验,本地测试用用就行,生产环境敢这么搞,等着被安全部门找上门!

三、额外排查点

  • 检查下本地hosts文件有没有把www.test-test.com映射到错误的IP,导致请求到了别的服务器,证书自然不匹配;
  • 如果目标服务用了CDN或者反向代理,得确认你调用的域名是不是CDN的域名,证书是不是CDN提供的,要是CDN证书里没这个域名也会出问题。

内容的提问来源于stack exchange,提问作者Ayoub EL ABOUSSI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:29:08