Problem Description
When using RestTemplate to send HTTPS requests, there is such a problem:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
RestTemplate does not support https protocol by default
solution:
The first is to ignore authentication
The second is to import certificates, which is more complicated (safer than the first)
solution:
Let me talk about the first solution here, ignoring the authentication
RestTemplateConfig
package com.test.config;
import java.nio.charset.Charset;
import java.util.List;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig{
@Bean("restTemplate")
public RestTemplate RestTemplate() {
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(30000);
httpRequestFactory.setConnectTimeout(30000);
httpRequestFactory.setReadTimeout(30000);
return new RestTemplate(httpRequestFactory);
}
/**
* 用于https请求,忽略认证
* @return unSSLRestTemplate
*/
@Bean("unSSLRestTemplate")
public RestTemplate restTemplateHttps() {
RestTemplate restTemplate = null;
try {
TrustStrategy acceptingTrustStrategy = (chain, authType) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
HttpClientBuilder clientBuilder = HttpClients.custom();
CloseableHttpClient httpClient = clientBuilder.setSSLSocketFactory(sslsf).build();
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(30000);
httpRequestFactory.setConnectTimeout(30000);
httpRequestFactory.setReadTimeout(30000);
httpRequestFactory.setHttpClient(httpClient);
restTemplate = new RestTemplate(httpRequestFactory);
//解决乱码
List<HttpMessageConverter<?>> httpMessageConverters = restTemplate.getMessageConverters();
httpMessageConverters.stream().forEach(httpMessageConverter ->{
if(httpMessageConverter instanceof StringHttpMessageConverter){
StringHttpMessageConverter messageConverter = (StringHttpMessageConverter)httpMessageConverter;
messageConverter.setDefaultCharset(Charset.forName("UTF-8"));
}
});
} catch (Exception e) {
e.printStackTrace();
}
return restTemplate;
}
}
test code
package com.test.service;
import javax.annotation.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* http请求&https请求
*/
@Service
public class TestService {
//http请求
@Resource(name = "restTemplate")
private RestTemplate restTemplate;
//https请求
@Resource(name = "unSSLRestTemplate")
private RestTemplate unSSLRestTemplate;
/**
* http请求
*/
public void interfaceHttp(JSONObject params) {
//参数
String json = params.toJSONString();
//请求头
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<String> formEntity = new HttpEntity<String>(json, headers);
restTemplate.postForObject(URL, formEntity, String.class);
}
/**
* https请求
*/
public void interfaceHttps(JSONObject params) {
//参数
String json = params.toJSONString();
//请求头
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<String> formEntity = new HttpEntity<String>(json, headers);
unSSLRestTemplate.postForObject(URL, formEntity, String.class);
}
}
Description: This is compatible with http and https requests, only need to specify the name