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

无法从PHP获取echo值到MyResultTextView,遇Volley SSL握手错误

解决Volley的SSLHandshakeException证书信任问题

兄弟,这个SSL握手错误我太熟了!本质就是你的Android App不信任目标PHP服务器的SSL证书,导致Volley在建立HTTPS连接时直接失败了。下面给你分场景提供两种靠谱的解决办法:

方法一:自定义信任所有证书(仅测试环境用!)

如果你只是在测试阶段图方便,不想折腾证书导入,可以用这个方法——但千万不要在生产环境用,这等于放弃HTTPS的安全防护,容易被中间人攻击。

首先写一个SSL工具类:

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class SSLUtils {
    public static void disableSSLCertificateChecking() {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        public X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }
                        public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                        public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                    }
            };

            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

然后在初始化Volley请求队列前调用这个方法:

// 先禁用证书校验(仅测试!)
SSLUtils.disableSSLCertificateChecking();

// 正常初始化Volley队列
RequestQueue queue = Volley.newRequestQueue(context);

// 发起请求获取PHP的echo值
StringRequest request = new StringRequest(Request.Method.GET, "你的PHP接口地址",
        response -> {
            // 这里就能拿到yes/no,直接设置到TextView
            MyResultTextView.setText(response);
        },
        error -> error.printStackTrace());

queue.add(request);

方法二:导入服务器证书到项目(生产环境推荐)

这是正规安全的做法,让App只信任你指定的服务器证书,既解决握手问题,又保证HTTPS的安全性。

  1. 获取服务器证书:用浏览器访问你的PHP服务器地址,点击地址栏的锁图标,导出证书为.crt格式(比如命名为server.crt)。
  2. 放入项目目录:把证书放到res/raw文件夹下(没有raw目录就新建一个)。
  3. 写自定义SSLSocketFactory:
import android.content.Context;
import android.util.Log;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

public class CustomSSLSocketFactory {
    public static SSLSocketFactory getSSLSocketFactory(Context context) {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream certInputStream = context.getResources().openRawResource(R.raw.server);
            Certificate ca;
            try {
                ca = cf.generateCertificate(certInputStream);
            } finally {
                certInputStream.close();
            }

            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            Log.e("CustomSSLSocket", "创建SSL工厂失败", e);
            return null;
        }
    }
}
  1. 给Volley配置自定义SSL:
// 获取自定义的SSL工厂
SSLSocketFactory sslSocketFactory = CustomSSLSocketFactory.getSSLSocketFactory(context);
if (sslSocketFactory != null) {
    HurlStack hurlStack = new HurlStack(null, sslSocketFactory);
    RequestQueue queue = Volley.newRequestQueue(context, hurlStack);

    // 发起请求
    StringRequest request = new StringRequest(Request.Method.GET, "你的PHP接口地址",
            response -> MyResultTextView.setText(response),
            error -> error.printStackTrace());
    
    queue.add(request);
}

另外补充:如果你的服务器用的是正规CA颁发的证书(比如Let's Encrypt),那可能是证书链不完整,这种情况可以联系服务器管理员补全证书链,或者在客户端导入完整的证书链。

内容的提问来源于stack exchange,提问作者RAM GOPAL VARMA ALLURI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:15:01