RestTemplate的使用

daqianmen發表於2021-09-09

技術之路,不進即退 。吾等菜雞應埋頭於技術之路,破甲斬棘。勿做土雞瓦狗,貪圖安逸。

今天我就來講一講我對於RestTemplate的一些理解,我相信大家肯定很多都會用。我今天把它拿出來講的原因,就是讓不清楚的人透過閱讀這篇文章能夠直接會用並且能懂得其中大概的原理。其實去年大學畢業到現在我可以說用過這個東西很多次了,由於網上的資料繁雜,所以當時只是單純想著會用就行,具體的一些瑣碎知識並未深究。

一 :概述

RestTemplate看名字就知道是“全家桶”的一員,其實我當時選擇它的原因也是因為這一點。順帶說一句,它的底層是對httpclient進行了封裝,在這裡就不喧賓奪主了,以後有機會我再寫一下相關的文章。

現在除了httpclient之外RPC 以及佇列的使用看可以說也是越來越廣泛了。在netty等NIO框架因為需要高效的傳輸所以往往選擇RPC,佇列則用於回撥以及裝置訊息之間的傳遞(我是用來儲存mqtt的訊息)。Http這個經久不衰的大佬自然不用多說,簡單,支援廣泛,高度相容性。

Http client 是否優秀可以從如下幾個方面進行判斷。

1. 連線池屬性

我們現在大多數使用的仍是HTTP1.1,它並不支援多路複用,因此我們為了避免頻繁的建立斷開連線損耗效能,連線池的是衡量是優秀的一個重要標準。

2. 超時時間屬性

設定時間超時屬性,可以說對於Httpclient是必須要設定的屬性。畢竟不可能我請求一個地址不可能無期限的等下去。你想象一下,你傳送了一個請求,對方一直無響應。這時候你發揮了你“不見不散”的良好品質,當臨終前的時候對方告訴你:“不好意思啊,介面我還沒寫呢。一路走好,兄弟。” 是不是極度尷尬。

3. 支援非同步
客戶端與服務端模式通常被人效能差的一個主要原因是因為它在過去很長的一段時間裡無法對非同步進行支援,這裡不僅僅指非阻塞IO,還包括非同步的程式設計模型。這句話也就是說,即便Http的協議棧是繼續非阻塞IO實現的,呼叫客戶端或服務端處理線的執行緒也會花費大量時間在等待IO上。

4.可以對請求和響應進行編解碼
簡潔來說我們不用直接面對原始訊息,因此編解碼大大的減少了開發的工作量。

5.擴充套件性
這個特性其實適用於任何地方,我曾聽一位大佬說過,以增量的方式去編寫程式碼,是一個架構師的必備的技能。而這個以增量的方式不僅僅是說無限的新增程式碼,而是當我們改動一部分程式碼而不影響其他程式碼。

RestTemplate的使用方法

圖片描述
ps:建議使用exchange ,其他方法都是對execute進行了封裝,都擁有各自的侷限性。

String url = "";

        try {
            User a = restTemplate.getForObject(url, User.class);
            System.out.println(a);
        } catch (HttpStatusCodeException e) {
            System.out.println(e.getResponseBodyAsString());
        }

圖片描述
透過第一個圖中我們可以看到,如果呼叫getForObject我們是沒辦法對編碼格式或者請求做一些操作,比如新增訊息頭資訊。

下面我們從頭講解一下,我以springboot專案為例。
首先我們需要配置一個關於RestTemplate的一個bean

@Configuration
public class RestConfig {

    @Bean
    @ConditionalOnMissingBean({RestOperations.class, RestTemplate.class})
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }

    @Bean
    @ConditionalOnMissingBean({ClientHttpRequestFactory.class})
    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(15000);
        factory.setConnectTimeout(15000);
        return factory;
    }

//下面被注的是對編碼進行了處理,但是一般是不需要的,如果你是第一次用的話,可以直接採用上面的配置,如果採用下面的是無法使用String進行接受的,這一點是需要注意的。
/*
    @Bean
    @ConditionalOnMissingBean({RestOperations.class, RestTemplate.class})
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        // return new RestTemplate(factory);

        RestTemplate restTemplate = new RestTemplate(factory);

        // 使用 utf-8 編碼集的 conver 替換預設的 conver(預設的 string conver 的編碼集為"ISO-8859-1")
        List> messageConverters = restTemplate.getMessageConverters();
        messageConverters.removeIf(converter -> converter instanceof StringHttpMessageConverter);
        messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));

        return restTemplate;
    }

    @Bean
    @ConditionalOnMissingBean({ClientHttpRequestFactory.class})
    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(15000);
        factory.setConnectTimeout(15000);
        return factory;
    }*/

}

圖片描述
透過上圖我們可以看到,採用的 APPLICATION_FORM_URLENCODED格式進行訊息傳送的。也可以選擇 APPLICATION_JSON_UTF8這種json格式。

如果返回值如下。

{"Result":"2","ResultMessage":"2003","ResultValue":"裝置不線上","TS":1531986891}

當HttpCode為200的時候才會又返回值,也就是說加入當你返回一個異常或者錯誤資訊的時候,你想修改HttpCode:比如404、500之類的就會丟擲異常。其中HttpServerError是以5開頭的異常,那麼……Client則是以4開頭的異常無疑。透過圖片我們能看出來他們都是繼承HttpStatusCodeException,如果有需求可以自行選擇。

詳細異常類如下:圖片描述

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1727/viewspace-2810738/,如需轉載,請註明出處,否則將追究法律責任。

相關文章