问题描述
使用RestTemplate发送HTTPS请求的时候,出现了这样的一个问题:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
RestTemplate 默认不支持https协议
解决方案:
第一种是忽略认证
第二种是导入证书,比较复杂(比第一种安全)
解决方案:
这里说一下第一种解决方案,忽略认证
版本:Spring Boot2.x
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;
}
}
测试代码
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);
}
}
说明:这里兼容http和https请求,只需要指定名称即可
更新:Spring Boot3.x依赖包不一样
版本:Spring Boot3.x
加上maven依赖文章来源:https://www.toymoban.com/news/detail-693069.html
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>
RestTemplateConfig文章来源地址https://www.toymoban.com/news/detail-693069.html
package com.test.config;
import java.nio.charset.Charset;
import java.util.List;
import javax.net.ssl.SSLContext;
//这里引用client5的包
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.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.setConnectionManager(PoolingHttpClientConnectionManagerBuilder
.create().setSSLSocketFactory(sslsf).build()).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;
}
}
到了这里,关于RestTemplate HTTPS请求忽略SSL证书的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!