Spring的RestTemplate,支持SimpleClientHttpRequestFactory、OkHttp3ClientHttpRequestFactory和HttpComponentsClientHttpRequestFactory。
其中,SimpleClientHttpRequestFactory不支持定制client。
如果要访问HTTPS网站,会抛异常:
java.security.cert.CertificateException: No subject alternative names present; nested exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
使用OkHttp3ClientHttpRequestFactory,可以定制client:
final OkHttpClient client = new OkHttpClient.Builder()
.hostnameVerifier((host, session) -> true)
.build();
final OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory(client);
测试,抛如下异常:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
继续配置策略
final X509TrustManager trustManager = new MyTrustManager();
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, null);
final OkHttpClient client = new OkHttpClient.Builder()
.hostnameVerifier((host, session) -> true)
.sslSocketFactory(sslContext.getSocketFactory(), trustManager)
.build();
final OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory(client);
其中,MyTrustManager如下
private static class MyTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
这样,就可以使用RestTemplate,访问HTTPS服务了。