在使用 Retrofit 进行网络请求时,如果出现 "java.security.cert.CertPathValidatorException: Trust anchor for certification path not found" 错误,通常是由于 SSL 证书验证失败导致的。以下是解决该问题的一种常见方法:
TrustManager
类,用于自定义 SSL 证书验证:import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class MyTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// 不做任何操作,接受所有客户端证书
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// 不做任何操作,接受所有服务器证书
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
TrustManager
来创建一个自定义的 SSLContext
:import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
// 创建 Retrofit 实例的工具类
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit == null) {
try {
TrustManager[] trustAllCerts = new TrustManager[]{new MyTrustManager()};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0])
.build();
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
}
return retrofit;
}
}
RetrofitClient
来创建 Retrofit 实例并进行网络请求:public class MainActivity extends AppCompatActivity {
private static final String BASE_URL = "https://example.com/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Retrofit retrofit = RetrofitClient.getClient(BASE_URL);
ApiService apiService = retrofit.create(ApiService.class);
// 进行网络请求
Call call = apiService.getSomeData();
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
// 处理响应
}
@Override
public void onFailure(Call call, Throwable t) {
// 处理错误
}
});
}
}
请注意,这种方法将绕过证书验证,可能会存在安全风险,请仅在开发和测试阶段使用。在正式发布时,建议使用有效的证书来确保数据的安全性。