RestTemplate发起HTTPS请求
文章目录
因为发起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) {// 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);
注:
RestTemplateBuilder
需要直接构建成RestTemplate
对象,而不能中间生成RestTemplateBuilder
对象。
文章作者 梧桐碎梦
上次更新 2022-02-13 14:29:11