1. 程式人生 > >使用HttpClient4來構建Spring RestTemplate

使用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包。

相關推薦

使用HttpClient4構建Spring RestTemplate

Spring RestTemplate簡單說明 現在REST服務已經很普及了,在我們的程式中,經常會需要呼叫REST API,這時候會有很多選擇,原始一點的JDK自帶的,再進一步點使用HttpClient,或者說如果我們使用Jersey這種框架的話,也會自帶rest client。但是我們專案使用的Sprin

Intellij中的Spring Initializr構建Spring Boot/Cloud工程

Spring Initializr Spring Initi Intellij 在之前的所有Spring Boot和Spring Cloud相關博文中,都會涉及Spring Boot工程的創建。而創建的方式多種多樣,我們可以通過Maven來手工構建或是通過腳手架等方式快速搭建,也可以通過《Spri

使用Intellij中的Spring Initializr構建Spring Boot/Cloud

Spring Initializr Spring Boot Spring Cloud 在之前的所有Spring Boot和Spring Cloud相關博文中,都會涉及Spring Boot工程的創建。而創建的方式多種多樣,我們可以通過Maven來手工構建或是通過腳手架等方式快速搭建,也可以通過《S

使用gradle構建Spring boot時遇到的問題

gradle預設把src/main/resources資料夾下的內容打包進jar包,所有applicaion.properties 和 public檔案需要放置這裡面 參考 https://github.com/spring-projects/spring-boot/is

Springboot(一):使用Intellij中的Spring Initializr快速構建Spring Boot工程

數據 web模塊 pan tell copy ice ima intellij pom 使用Intellij中的Spring Initializr來快速構建Spring Boot工程   New---Project   可以看到圖所示的創建功能窗口。其中Initial S

使用Intellij中的Spring Initializr快速構建Spring Boot/Clou

Spring Initializr Spring Boot Intellij 在之前的所有Spring Boot和Spring Cloud相關博文中,都會涉及Spring Boot工程的創建。而創建的方式多種多樣,我們可以通過Maven來手工構建或是通過腳手架等方式快速搭建,也可以通過《Sprin

Spring Cloud Spring Boot mybatis分布式微服務雲架構(二)使用Intellij中的Spring Initializr快速構建Spring Boot/Cloud工程

follow 體驗 alt initial ali roo 進行 依賴管理 img 在之前的所有Spring Boot和Spring Cloud相關博文中,都會涉及Spring Boot工程的創建。而創建的方式多種多樣,我們可以通過Maven來手工構建或是通過腳手架等方式快

用 Docker、Gradle 構建、運行、發布一個 Spring Boot 應用

repo com ase exp base ide 默認 相關 conf 本文演示了如何用 Docker、Gradle 來構建、運行、發布來一個 Spring Boot 應用。Docker 簡介Docker 是一個 Linux 容器管理工具包,具備“社交”方面,允許用戶發布

Spring Boot 入門篇 (一) 使用Intellij中的Spring Initializr快速構建Spring Boot/Cloud工程

使用idea 構建 springboot 專案 原文地址:使用Intellij中的Spring Initializr來快速構建Spring Boot/Cloud工程 在之前的所有Spring Boot和Spring Cloud相關博文中,都會涉及Spring Boot工程的建立。而建立的方式

使用spring官網 SPRING INITIALIZR 構建專案結構(地址:http://start.spring.io/)

搭建步驟: 1.使用上述方法構建專案 2.將下載的壓縮包解壓 3.將解壓之後的壓縮包作為一個maven專案匯入eclipse中 4.然後在pom.xml檔案中將下面的依賴進行修改 <dependency> <groupId>org.

Spring Boot 入門篇 (一) 使用Intellij中的Spring Initializr快速構建Spring Boot/Cloud工程

使用idea 構建 springboot 專案 在之前的所有Spring Boot和Spring Cloud相關博文中,都會涉及Spring Boot工程的建立。而建立的方式多種多樣,我們可以通過Maven來手工構建或是通過腳手架等方式快速搭建,也可以通過《Spring

使用Intellij中的Spring Initializr快速構建Spring Boot/Cloud工程(十五)

在之前的所有Spring Boot和Spring Cloud相關博文中,都會涉及Spring Boot工程的建立。而建立的方式多種多樣,我們可以通過Maven來手工構建或是通過腳手架等方式快速搭建,也可以通過《Spring Boot快速入門》一文中提到的SPRING INITIALIZR頁面工具來建立,相信每

使用IntelliJ IDEA中的Spring Initializr快速構建Spring Boot/Cloud工程

我相信許多初學者都看了Spring Boot和Spring Cloud相關的博文中,都會涉及Spring Boot工程的建立的問題。而一般所看到的都是使用IntelliJ IDEA 工具來建立,並且方

使用shiro的會話管理和redis快取管理構建登入模組spring+struts+hibernate(SSH)

     shiro是一個很好用的安全框架,主要表現在使用者認證,許可權認證,會話管理,如果想優化還可以做Cache管理,我們不需要做太多工作在使用者身份token安全方面(記錄shiro及用redis開發的步驟及一些問題,因為網上很多資料都不給全程式碼讓小白沒法理解,這裡我

C實現頭插法和尾插法構建單鏈表(不帶頭結點)

res rgb eof uci fun while data 尾插法 輸入數據 鏈表的構建事實上也就是不斷插入節點的過程。而節點的插入能夠分為頭插法和尾插法。頭插法就是在頭結點後插入該節點,始終把該節點作為第一個節點。尾插法就是在鏈表的最後一個節點處插入元

spring restTemplate 用法

方式 blog string 鍵值對 gin for ava pla div 發出get請求,方式一 String url = serverUrl+"/path/path?id={id}"; int i = restTemplate.get

idea構建spring源碼閱讀環境

4.0 exist 例如 9.png tro git ide file cnblogs (一)安裝git和Gradle Spring項目托管在github之上,基於Gradle來構建項目。所以要想搭建Spring的閱讀環境,首先需要安裝github和Gradle。對於一個程

spring boot系列01--快速構建spring boot項目

註解 spring auto enc java ram fig 技術 configure 最近的項目用spring boot 框架 借此學習了一下 這裏做一下總結記錄 非常便利的一個框架 它的優缺點我就不在這背書了 想了解的可以自行度娘谷歌 說一下要寫什麽吧 其實還真不

構建Spring Cloud微服務分布式雲架構詳細步驟

hystrix 搭建過程 urb ron title target 過程 運用 發的 大型企業分布式微服務雲架構服務組件 實現模塊化、微服務化、原子化、灰度發布、持續集成 commonservice eurekaNetflix 雲端服務發現,一個基於 REST 的服務,用於

構建Spring Boot應用鏡像

unzip pin sse java 我們 pre lib 鏡像 cmd 1、在Dockerfile所在目錄,解壓縮maven生成的jar包 unzip <path-to-app-jar>.jar -d app 2、Dockerfile 我們把應用的內容分成