歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 使用HttpClient4來構建Spring RestTemplate

使用HttpClient4來構建Spring RestTemplate

日期:2017/3/1 9:28:20   编辑:Linux編程

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.linuxidc.com/Linux/2015-06/119099.htm 以及我前面的一篇:http://www.linuxidc.com/Linux/2015-06/119098p2.htm ,這裡就不具體講了,可以網上搜索相關資料。
下面寫寫代碼來描述下怎麼通過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包。

使用HttpClient實現文件的上傳下載 http://www.linuxidc.com/Linux/2014-07/104303.htm

Android 實現 HttpClient 請求Https http://www.linuxidc.com/Linux/2014-05/102306.htm

Android使用HttpClient下載圖片 http://www.linuxidc.com/Linux/2014-05/101855.htm

HttpClient使用詳解 http://www.linuxidc.com/Linux/2014-08/104945.htm

Copyright © Linux教程網 All Rights Reserved