您的位置:首页 > 编程语言 > Java开发

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();
}
}


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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring rest ssl