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

Jersey调用外部API遇SSL证书匹配错误,如何禁用SSL校验?

问题描述

我正尝试通过Java应用调用外部API,使用Jersey发起请求,代码如下:

ClientConfig clientConfig = new ClientConfig();
//Open Digest authentication

clientConfig.register(JacksonFeature.class);
//Create new rest client
Client client = ClientBuilder.newClient( clientConfig );

//Set the url
WebTarget webTarget = client.target(rootUrl);
Invocation.Builder invocationBuilder =  webTarget.request(javax.ws.rs.core.MediaType.APPLICATION_JSON);

MultivaluedMap<String, Object> header = new MultivaluedHashMap<>();
header.add("UserName", username);
header.add("Password", password);

invocationBuilder.headers(header);
logger.info("Initialisation of cashout service successful");

// create request
Gson gson = new Gson();
String transactionString = gson.toJson(request);



try {
    // start the response
    Response response = invocationBuilder.put(Entity.entity(transactionString, javax.ws.rs.core.MediaType.APPLICATION_JSON));
    //We check if the response is ok
    if(response.getStatus() == 200) {
        logger.info("The paiement is done, we got 200 code return");
        responseData = response.readEntity(AirtimePaymentResponse.class);

        logger.info("the response data is {} ", responseData);
    }else {
        logger.info("error during the paiement");
        throw new GGException("Error during the paiement", HttpStatus.valueOf(response.getStatus()));
    }
}catch (Exception e) {
    throw new GGException(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}

但遇到错误:javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching xxx.com found。请问如何在代码中禁用SSL校验以运行在不安全模式?我尝试了多种方案但均未成功,恳请解答。

解决方案

要在Jersey客户端中禁用SSL校验(仅用于测试环境,生产环境绝对禁止使用),需要自定义SSLContext和HostnameVerifier,具体实现如下:

  • 创建信任所有证书的TrustManager,跳过证书合法性校验
  • 创建跳过主机名匹配校验的HostnameVerifier
  • 将自定义配置注入到Jersey Client的配置中

完整修改后的代码:

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import java.security.cert.X509Certificate;
import java.security.NoSuchAlgorithmException;
import java.security.KeyManagementException;

// 保留原有导入类

public class YourServiceClass {
    // 原有类属性和方法

    public void executePaymentRequest() {
        try {
            // 1. 定义信任所有证书的TrustManager
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    @Override
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                    @Override
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                }
            };

            // 2. 初始化自定义SSLContext
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // 3. 定义跳过主机名校验的HostnameVerifier
            HostnameVerifier skipHostnameVerify = new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };

            // 4. 配置Jersey Client
            ClientConfig clientConfig = new ClientConfig();
            clientConfig.register(JacksonFeature.class);
            // 注入自定义SSL上下文和主机名校验器
            clientConfig.property("jersey.config.client.ssl.context", sslContext);
            clientConfig.property("jersey.config.client.hostname.verifier", skipHostnameVerify);

            Client client = ClientBuilder.newClient(clientConfig);

            // --- 以下为原有业务代码 ---
            WebTarget webTarget = client.target(rootUrl);
            Invocation.Builder invocationBuilder = webTarget.request(javax.ws.rs.core.MediaType.APPLICATION_JSON);

            MultivaluedMap<String, Object> header = new MultivaluedHashMap<>();
            header.add("UserName", username);
            header.add("Password", password);

            invocationBuilder.headers(header);
            logger.info("Initialisation of cashout service successful");

            Gson gson = new Gson();
            String transactionString = gson.toJson(request);

            try {
                Response response = invocationBuilder.put(Entity.entity(transactionString, javax.ws.rs.core.MediaType.APPLICATION_JSON));
                if(response.getStatus() == 200) {
                    logger.info("The paiement is done, we got 200 code return");
                    responseData = response.readEntity(AirtimePaymentResponse.class);
                    logger.info("the response data is {} ", responseData);
                }else {
                    logger.info("error during the paiement");
                    throw new GGException("Error during the paiement", HttpStatus.valueOf(response.getStatus()));
                }
            }catch (Exception e) {
                throw new GGException(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            throw new GGException("Failed to configure SSL context", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

重要提示

  • 禁用SSL校验会完全消除HTTPS的安全防护,存在中间人攻击风险,仅允许在本地测试或非生产环境临时使用。
  • 生产环境的正确解决方式:
    • 确认API域名的SSL证书包含正确的Subject Alternative Name(SAN)字段
    • 将该证书导入到Java系统信任库(cacerts)中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:35:25