因为发起HTTPS请求时需要验证服务端SSL证书,所以在此有两种解决办法,一是导入证书,二是忽略证书的校验。
在此我采用的是忽略证书的校验。
首先使用 RestTemplateBuilder 来构建一个 RestTemplate ,而非使用默认。requestFactory() 方法用来设置 ClientHttpRequestFactory 。SimpleClientHttpRequestFactory 是Spring内置的默认实现,实现了 ClientHttpRequestFactory 接口,我们需要重写其 prepareConnection() 方法,在此方法里实现对 HttpURLConnection 的重新处理,忽略对证书的校验。
代码:
public class HttpsClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
@Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
try {
if (connection instanceof HttpsURLConnection) {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
TrustStrategy anyTrustStrategy = (x509Certificates, s) -> true;
SSLContext ctx = SSLContexts.custom().loadTrustMaterial(trustStore, anyTrustStrategy).build();
((HttpsURLConnection) connection).setSSLSocketFactory(ctx.getSocketFactory());
((HttpsURLConnection) connection).setHostnameVerifier((s, sslSession) -> true);
HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
super.prepareConnection(httpsConnection, httpMethod);
} else {
super.prepareConnection(connection, httpMethod);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
String url = "https://xxx.xxx.xxx";
RestTemplate restTemplate = new RestTemplateBuilder()
.requestFactory(HttpsClientHttpRequestFactory::new)
.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);
注:
RestTemplateBuilder 需要直接构建成 RestTemplate 对象,而不能中间生成 RestTemplateBuilder 对象。
|