RestTemplate是Spring提供的用于访问Rest服务的客户端,提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。RestTemplate 默认使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接(SimpleClientHttpRequestFactory),不需要配置证书信息,但如果调用https请求时的证书不合法,会报”unable to find valid certification path to requested target“错误。这时可以使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务来配置证书。
代码如下:
import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import org.apache.http.client.config.RequestConfig; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("httpClientFactory") public class HttpClientFactory { @Value("${restclient.readTimeout}") private int readTimeout; @Value("${restclient.connectTimeout}") private int connectTimeout; public CloseableHttpClient acceptsUntrustedCertsHttpClient() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException { SSLContext sslcontext = SSLContexts.custom().setSecureRandom(new SecureRandom()) .loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(readTimeout) .setConnectTimeout(connectTimeout).setStaleConnectionCheckEnabled(true).build(); return HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(defaultRequestConfig).build(); } } 初始化httpClient
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <bean id="httpClient" factory-bean="httpClientFactory" factory-method="acceptsUntrustedCertsHttpClient" /> <bean id="clientHttpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"> <constructor-arg ref="httpClient" /> </bean> <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> <constructor-arg index="0"> <list> <bean id="byteArrayHttpMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean> <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"></constructor-arg> </bean> <bean id="resourceHttpMessageConverter" class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean> <bean id="sourceHttpMessageConverter" class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean> <bean id="allEncompassingFormHttpMessageConverter" class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter"></bean> </list> </constructor-arg> <property name="requestFactory" ref="clientHttpRequestFactory" /> </bean> </beans> 配置resttemplate