zoukankan      html  css  js  c++  java
  • 使用HttpClient4来构建Spring RestTemplate

    Spring RestTemplate简单说明

    现在REST服务已经很普及了,在我们的程序中,经常会需要调用REST API,这时候会有很多选择,原始一点的JDK自带的,再进一步点使用HttpClient,或者说如果我们使用Jersey这种框架的话,也会自带rest client。但是我们项目使用的SpringMVC,所以直接使用RestTemplate。使用RestTemplate比直接使用Httpclient简单很多,同时也可以借助httpclient来实现RestTemplate。

    通过使用RestTemplate仅仅只需要写几行代码,就可以完成直接使用httpclient很多行代码的事情,具体见:https://spring.io/blog/2009/03/27/rest-in-spring-3-resttemplate

    RestTemplate有三个构造函数:

    1. 默认构造函数,默认使用SimpleClientHttpRequestFactory,使用JDK自带的java.net包进行网络传输。
    2. public RestTemplate(ClientHttpRequestFactory requestFactory)。传入一个ClientHttpRequestFactory,ClientHttpRequestFactory在Spring中的实现有很多个,如HttpComponentsClientHttpRequestFactory,Netty4ClientHttpRequestFactory等,具体的可以看代码,这里只介绍HttpComponentsClientHttpRequestFactory,需要用到 HttpClient4.
    3. public RestTemplate(List<HttpMessageConverter<?>> messageConverters),使用SpringMvc的应该对HttpMessageConverter很熟悉了,RestTemplate默认会给我们设置好常用的HttpMessageConverter,我一般很少使用到这个构造方法。

    HttpComponentsClientHttpRequestFactory

    这里主要讨论的是通过第二个构造方法来使用HttpClient4 来进行网络传输。下面我们来看下HttpComponentsClientHttpRequestFactory这个类。先看看他的构造方法

    
    	/**
    	 * Create a new instance of the {@code HttpComponentsClientHttpRequestFactory}
    	 * with a default {@link HttpClient}.
    	 */
    	public HttpComponentsClientHttpRequestFactory() {
    		this(HttpClients.createSystem());
    	}
    
    	/**
    	 * Create a new instance of the {@code HttpComponentsClientHttpRequestFactory}
    	 * with the given {@link HttpClient} instance.
    	 * <p>As of Spring Framework 4.0, the given client is expected to be of type
    	 * {@link CloseableHttpClient} (requiring HttpClient 4.3+).
    	 * @param httpClient the HttpClient instance to use for this request factory
    	 */
    	public HttpComponentsClientHttpRequestFactory(HttpClient httpClient) {
    		Assert.notNull(httpClient, "'httpClient' must not be null");
    		Assert.isInstanceOf(CloseableHttpClient.class, httpClient, "'httpClient' is not of type CloseableHttpClient");
    		this.httpClient = (CloseableHttpClient) httpClient;
    	}
    

    如果我们不指定一个HttpClient的话,会默认帮我们创建一个,如果我们程序调用比较频繁的话,为了提高性能,会考虑使用PoolingHttpClientConnectionManager来构建HttpClient,这时候就会使用到第二个。如何使用PoolingHttpClientConnectionManager来创建HttpClient呢?可以参考几个文章:http://www.yeetrack.com/?p=782 以及我前面的一篇:http://www.cnblogs.com/hupengcool/p/4554525.html ,这里就不具体讲了,可以网上搜索相关资料。
    下面写写代码来描述下怎么通过HttpComponentsClientHttpRequestFactory来创建RestTemplate,为了方便创建HttpClient的代码我就直接使用我前面文章中的代码:

    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    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.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.ssl.SSLContextBuilder;
    import org.apache.http.ssl.TrustStrategy;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    import java.security.KeyManagementException;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    /**
     * Created by Administrator on 2015/6/8.
     */
    public class HttpClientUtils {
    
        public static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
            HttpClientBuilder b = HttpClientBuilder.create();
    
            // setup a Trust Strategy that allows all certificates.
            //
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    return true;
                }
            }).build();
            b.setSSLContext(sslContext);
    
            // don't check Hostnames, either.
            //      -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
    
            // here's the special part:
            //      -- need to create an SSL Socket Factory, to use our weakened "trust strategy";
            //      -- and create a Registry, to register it.
            //
            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.getSocketFactory())
                    .register("https", sslSocketFactory)
                    .build();
    
            // now, we create connection-manager using our Registry.
            //      -- allows multi-threaded use
            PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
            connMgr.setMaxTotal(200);
            connMgr.setDefaultMaxPerRoute(100);
            b.setConnectionManager( connMgr);
    
            // finally, build the HttpClient;
            //      -- done!
            CloseableHttpClient client = b.build();
    
            return client;
        }
    
    }
    

    创建并使用RestTemplate

            CloseableHttpClient httpClient = HttpClientUtils.acceptsUntrustedCertsHttpClient();
            HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
            RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
            String result = restTemplate.getForObject("http://www.baidu.com",String.class);
            System.out.println(result);
    

    那么问题来了,我们既然是使用Spring,那肯定希望把他RestTemplate配置成Spring bean来使用,HttpClient是线程安全的,他可以在程序中共享,创建一个成Spring bean刚好。下面是xml配置。

       <bean id="httpClient" class="com.hupengcool.util.HttpClientUtils" 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 ref="clientHttpRequestFactory" />
        </bean>
    

    开始使用Spring RestTemplate吧。。。。。
    PS:项目中除了Spring相关jar包外。需要添加HttpClient4.5,jackson 2.x的jar包。

  • 相关阅读:
    第2阶段冲刺2
    第2阶段冲刺1
    在Ubuntu下安装VWMare tools
    mysql命令行修改密码
    Ubuntu设置环境变量
    java输出程序运行时间
    Hadoop之环境搭建
    MapReduce实现WordCount
    大数据技术之kettle(2)——练习三个基本操作
    大数据技术之kettle(1)——安装
  • 原文地址:https://www.cnblogs.com/hupengcool/p/4590006.html
Copyright © 2011-2022 走看看