RestTemplate实践
2016-07-25 11:29
344 查看
什么是RestTemplate?
RestTemplate是spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用Java.net包下的实现创建HTTP 请求,可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式。ClientHttpRequestFactory接口主要提供了两种实现方式
一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接。
一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。
默认resetTemplate使用的是jdk的net提供的方式,如果需要配置证书需要更改底层的实现方式,restTemplate的父类中HttpAccessor有个setRequestFactory方法可以配置底层工厂的实现方式
下面的主要是对ssl请求的一些封装,
/**
* 对httpclient的一些封装,主要用于发送ssl的请求
* Created by worke on 4/23/16.
*/
public class HttpComponenUtil {
/**
* 返回一个请求头
*
* @param mediaType 请求类型例如MediaType.APPLICATION_JSON
* @param headerMap 请求头信息
* @return
*/
public static HttpHeaders getHeaders(MediaType mediaType, Map<String, String> headerMap) {
HttpHeaders httpHeaders = new HttpHeaders();
//设置请求的类型
httpHeaders.setContentType(mediaType);
//请求头信息
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
httpHeaders.add(entry.getKey(), entry.getValue());
}
return httpHeaders;
}
/**
*
* @param mediaType 请求类型例如MediaType.APPLICATION_JSON
* @param headerMap 请求头信息
* @param body 请求的参数
* @return
*/
public static HttpEntity getHttpEntity(MediaType mediaType, Map<String, String> headerMap, String body) {
return new HttpEntity(body, getHeaders(mediaType, headerMap));
}
/**
* 请求的参数封装
*
* @param httpHeaders 请求头信息
* @param body 请求参数
* @return
*/
public static HttpEntity getHttpEntity(HttpHeaders httpHeaders, String body) {
return new HttpEntity(body, httpHeaders);
}
/**
* HttpClient创建者
*
* @param LgsslKeystoreFile
* @param lgsslKeystorePass
* @return
* @throws Exception
*/
public static HttpClientBuilder getHttpClientBuilder(String LgsslKeystoreFile, String lgsslKeystorePass) throws Exception {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
URL sslFileUrl = HttpComponenUtil.class.getClassLoader().getResource(LgsslKeystoreFile);
FileInputStream fin = new FileInputStream(new File(sslFileUrl.getPath()));
System.setProperty("javax.net.ssl.trustStore", sslFileUrl.getPath());
trustStore.load(fin, lgsslKeystorePass.toCharArray());
fin.close();
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new X509HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
@Override
public void verify(String host, SSLSocket ssl) throws IOException {
}
@Override
public void verify(String host, X509Certificate cert) throws SSLException {
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
}
});
return HttpClients.custom().setSSLSocketFactory(sslsf);
}
/**
* ssl的请求
*
* @param LgsslKeystoreFile classpath下ssl文件的名称
* @param lgsslKeystorePass 密钥密码
* @return
*/
public static HttpClient getSSLHttpClient(String LgsslKeystoreFile, String lgsslKeystorePass) throws Exception {
return getHttpClientBuilder(LgsslKeystoreFile, lgsslKeystorePass).build();
}
/**
* ssl类型工厂
* post请求
*
* @param httpClient
* @return
* @throws Exception
*/
public static HttpComponentsClientHttpRequestFactory getSSLClientHttpRequestFactory(HttpClient httpClient) throws Exception {
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
/**
* 和临工对接接口时的sslClientHttpFactoty工厂
* 发送get请求
*
* @param
* @return
*/
public static ClientHttpRequestFactory getSSLClientHttpRequestFactoryForGET(String sslFile, String sslPass, List<Header> headMap) throws Exception {
return new HttpComponentsClientHttpRequestFactory(getHttpClientBuilder(sslFile, sslPass).setDefaultHeaders(headMap).build());
}
}
也可以在spring容器初始化的时候来指定底层的实现方式,主要对于ssl需要证书的方式
@Configuration
@PropertySource("classpath:config.properties")
public class RestClientConfig {
@Bean
public RestOperations restOperations(ClientHttpRequestFactory clientHttpRequestFactory) throws Exception {
return new RestTemplate(clientHttpRequestFactory);
}
@Bean
public ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient) {
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
@Bean
public HttpClient httpClient(@Value("${keystore.file}") String file,
@Value("${keystore.pass}") String password) throws Exception {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File(file));
try {
trustStore.load(instream, password.toCharArray());
} finally {
instream.close();
}
SSLContext sslcontext =
SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
SSLConnectionSocketFactory sslsf =
new SSLConnectionSocketFactory(sslcontext, new String[]{,"TLSv1.2"}, null,
BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
另外对spring的restTemplate的请求乱码问题可用如下方式解决!
HttpHeaders headers =new HttpHeaders();
MediaType type = MediaType.APPLICATION_JSON_UTF8;
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
这样写对spring的版本有个写要求在spring-web的4.0是不支持的在4.2.7是ok的,在4.0之前可以这样写
MediaType.parseMediaType("application/json; charset=UTF-8");
更多详情 http://blog.csdn.net/u010476464/article/details/50067079
RestTemplate是spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用Java.net包下的实现创建HTTP 请求,可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式。ClientHttpRequestFactory接口主要提供了两种实现方式
一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接。
一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。
默认resetTemplate使用的是jdk的net提供的方式,如果需要配置证书需要更改底层的实现方式,restTemplate的父类中HttpAccessor有个setRequestFactory方法可以配置底层工厂的实现方式
下面的主要是对ssl请求的一些封装,
/**
* 对httpclient的一些封装,主要用于发送ssl的请求
* Created by worke on 4/23/16.
*/
public class HttpComponenUtil {
/**
* 返回一个请求头
*
* @param mediaType 请求类型例如MediaType.APPLICATION_JSON
* @param headerMap 请求头信息
* @return
*/
public static HttpHeaders getHeaders(MediaType mediaType, Map<String, String> headerMap) {
HttpHeaders httpHeaders = new HttpHeaders();
//设置请求的类型
httpHeaders.setContentType(mediaType);
//请求头信息
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
httpHeaders.add(entry.getKey(), entry.getValue());
}
return httpHeaders;
}
/**
*
* @param mediaType 请求类型例如MediaType.APPLICATION_JSON
* @param headerMap 请求头信息
* @param body 请求的参数
* @return
*/
public static HttpEntity getHttpEntity(MediaType mediaType, Map<String, String> headerMap, String body) {
return new HttpEntity(body, getHeaders(mediaType, headerMap));
}
/**
* 请求的参数封装
*
* @param httpHeaders 请求头信息
* @param body 请求参数
* @return
*/
public static HttpEntity getHttpEntity(HttpHeaders httpHeaders, String body) {
return new HttpEntity(body, httpHeaders);
}
/**
* HttpClient创建者
*
* @param LgsslKeystoreFile
* @param lgsslKeystorePass
* @return
* @throws Exception
*/
public static HttpClientBuilder getHttpClientBuilder(String LgsslKeystoreFile, String lgsslKeystorePass) throws Exception {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
URL sslFileUrl = HttpComponenUtil.class.getClassLoader().getResource(LgsslKeystoreFile);
FileInputStream fin = new FileInputStream(new File(sslFileUrl.getPath()));
System.setProperty("javax.net.ssl.trustStore", sslFileUrl.getPath());
trustStore.load(fin, lgsslKeystorePass.toCharArray());
fin.close();
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new X509HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
@Override
public void verify(String host, SSLSocket ssl) throws IOException {
}
@Override
public void verify(String host, X509Certificate cert) throws SSLException {
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
}
});
return HttpClients.custom().setSSLSocketFactory(sslsf);
}
/**
* ssl的请求
*
* @param LgsslKeystoreFile classpath下ssl文件的名称
* @param lgsslKeystorePass 密钥密码
* @return
*/
public static HttpClient getSSLHttpClient(String LgsslKeystoreFile, String lgsslKeystorePass) throws Exception {
return getHttpClientBuilder(LgsslKeystoreFile, lgsslKeystorePass).build();
}
/**
* ssl类型工厂
* post请求
*
* @param httpClient
* @return
* @throws Exception
*/
public static HttpComponentsClientHttpRequestFactory getSSLClientHttpRequestFactory(HttpClient httpClient) throws Exception {
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
/**
* 和临工对接接口时的sslClientHttpFactoty工厂
* 发送get请求
*
* @param
* @return
*/
public static ClientHttpRequestFactory getSSLClientHttpRequestFactoryForGET(String sslFile, String sslPass, List<Header> headMap) throws Exception {
return new HttpComponentsClientHttpRequestFactory(getHttpClientBuilder(sslFile, sslPass).setDefaultHeaders(headMap).build());
}
}
也可以在spring容器初始化的时候来指定底层的实现方式,主要对于ssl需要证书的方式
@Configuration
@PropertySource("classpath:config.properties")
public class RestClientConfig {
@Bean
public RestOperations restOperations(ClientHttpRequestFactory clientHttpRequestFactory) throws Exception {
return new RestTemplate(clientHttpRequestFactory);
}
@Bean
public ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient) {
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
@Bean
public HttpClient httpClient(@Value("${keystore.file}") String file,
@Value("${keystore.pass}") String password) throws Exception {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File(file));
try {
trustStore.load(instream, password.toCharArray());
} finally {
instream.close();
}
SSLContext sslcontext =
SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
SSLConnectionSocketFactory sslsf =
new SSLConnectionSocketFactory(sslcontext, new String[]{,"TLSv1.2"}, null,
BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
config.properties keystore.file=${user.home}/.keystore keystore.pass=changeit
另外对spring的restTemplate的请求乱码问题可用如下方式解决!
HttpHeaders headers =new HttpHeaders();
MediaType type = MediaType.APPLICATION_JSON_UTF8;
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
这样写对spring的版本有个写要求在spring-web的4.0是不支持的在4.2.7是ok的,在4.0之前可以这样写
MediaType.parseMediaType("application/json; charset=UTF-8");
更多详情 http://blog.csdn.net/u010476464/article/details/50067079
相关文章推荐
- 访问Nginx发生SSL connection error的一种情况
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring和ThreadLocal
- Spring Boot 开发微服务
- Spring AOP动态代理-切面
- MySQL复制解决方案(Replication Solutions)
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- 解析Silverlight调用WCF/Rest异常的解决方法
- 模拟Spring的简单实现
- Spring整合WebSocket应用示例(上)
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- 监听器获取Spring配置文件的方法
- Java利用Sping框架编写RPC远程过程调用服务的教程
- springmvc 发送ajax出现中文乱码的解决方法汇总