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

OkHttp升级至OkHttp3遇setSslSocketFactory配置空指针异常求助

修复OkHttp3升级后的javax.net.ssl.SSLException: java.lang.NullPointerException问题

问题根源

  1. 未初始化的standardTrustManager:自定义TrustManager中的standardTrustManager变量始终为null,执行到standardTrustManager.checkServerTrusted或checkClientTrusted时直接抛出NPE。
  2. SSLContext ctx为null时调用getSocketFactory():当trustSelfSigned为false时,ctx未被初始化,构建OkHttpClient时调用.sslSocketFactory(ctx.getSocketFactory())触发NPE。
  3. 冗余的硬编码代理配置:原逻辑通过JVM参数配置代理,新代码硬编码代理逻辑,与原有设计冲突。

修复方案

OkHttpClient client() {
    if (client != null)
        return client;
    if (System.getenv("trustSelfSignedCert") != null
            && System.getenv("trustSelfSignedCert").equalsIgnoreCase("true"))
        trustSelfSigned = true;
    if (System.getProperty("trustSelfSignedCert") != null
            && System.getProperty("trustSelfSignedCert").equalsIgnoreCase("true"))
        trustSelfSigned = true;

    OkHttpClient.Builder builder = new OkHttpClient.Builder()
            .writeTimeout(timeout * 1000L, TimeUnit.MILLISECONDS)
            .readTimeout(timeout * 1000L, TimeUnit.MILLISECONDS);

    if (trustSelfSigned) {
        try {
            // 获取系统默认TrustManager,避免空指针
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore) null);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            X509TrustManager standardTrustManager = (X509TrustManager) trustManagers[0];

            TrustManager[] customCerts = new TrustManager[]{new X509TrustManager() {
                private final X509TrustManager defaultTrustManager = standardTrustManager;

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return defaultTrustManager.getAcceptedIssuers();
                }

                @Override
                public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
                    if ((certificates != null) && (certificates.length == 1)) {
                        certificates[0].checkValidity();
                    } else {
                        defaultTrustManager.checkServerTrusted(certificates, authType);
                    }
                }

                @Override
                public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
                    defaultTrustManager.checkClientTrusted(certificates, authType);
                }
            }};

            SSLContext ctx = SSLContext.getInstance(tls);
            ctx.init(null, customCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
            // OkHttp3要求sslSocketFactory必须同时传入TrustManager
            builder.sslSocketFactory(ctx.getSocketFactory(), standardTrustManager);
        } catch (java.security.GeneralSecurityException ex) {
            // 建议不要静默吞异常,添加日志便于排查
            ex.printStackTrace();
        }
    }
    // 移除硬编码代理,OkHttp会自动读取JVM代理参数
    return client = builder.build();
}

关键修复点说明

  • 初始化默认TrustManager:通过TrustManagerFactory获取系统默认的X509TrustManager,解决自定义TrustManager内部空指针问题。
  • 条件化配置SSL:仅当trustSelfSigned为true时才设置自定义SSLSocketFactory,否则使用OkHttp默认实现,避免ctx为null时的调用错误。
  • 符合OkHttp3规范:调用sslSocketFactory时必须同时传入X509TrustManager,避免版本兼容问题。
  • 移除硬编码代理:保留原设计,让OkHttp自动读取JVM参数配置的代理。
  • 优化异常处理:不再静默吞掉安全异常,便于后续排查问题。

内容的提问来源于stack exchange,提问作者Ricky V.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 10:24:43