Spring 5 - 使用RestTemplate,访问HTTPS服务

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服务了。

经验分享 程序员 微信小程序 职场和发展