RestTemplate实践

什么是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



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值