RestTemplate发起HTTPS请求

因为发起HTTPS请求时需要验证服务端SSL证书,所以在此有两种解决办法,一是导入证书,二是忽略证书的校验。

在此我采用的是忽略证书的校验。

首先使用 RestTemplateBuilder来构建一个 RestTemplate,而非使用默认。requestFactory()方法用来设置 ClientHttpRequestFactorySimpleClientHttpRequestFactory是Spring内置的默认实现,实现了 ClientHttpRequestFactory接口,我们需要重写其 prepareConnection()方法,在此方法里实现对 HttpURLConnection的重新处理,忽略对证书的校验。

代码:

public class HttpsClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
    @Override
    protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
        try {
            if (connection instanceof HttpsURLConnection) {// https协议,修改协议版本
                KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
                // 信任任何链接,忽略对证书的校验
                TrustStrategy anyTrustStrategy = (x509Certificates, s) -> true;
                //自定义SSLContext
                SSLContext ctx = SSLContexts.custom().loadTrustMaterial(trustStore, anyTrustStrategy).build();
                // ssl问题
                ((HttpsURLConnection) connection).setSSLSocketFactory(ctx.getSocketFactory());
                //解决No subject alternative names matching IP address xxx.xxx.xxx.xxx found问题
                ((HttpsURLConnection) connection).setHostnameVerifier((s, sslSession) -> true);
                HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
                super.prepareConnection(httpsConnection, httpMethod);
            } else { // http协议
                super.prepareConnection(connection, httpMethod);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
    
String url = "https://xxx.xxx.xxx";
RestTemplate restTemplate = new RestTemplateBuilder()
		.requestFactory(HttpsClientHttpRequestFactory::new)
		//basic认证
		.basicAuthentication("username", "password")
		.build();
HttpHeaders headers = new HttpHeaders();
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
String str = response.getBody();
System.out.println(str);
    

注:

  1. RestTemplateBuilder 需要直接构建成 RestTemplate对象,而不能中间生成 RestTemplateBuilder对象。

你可能感兴趣的:(https,ssl,http)