如何使用RestTemplate訪問restful服務(wù)

一. 什么是RestTemplate

傳統(tǒng)情況下在java代碼里訪問restful服務(wù)菱父,一般使用ApacheHttpClient库正。不過此種方法使用起來太過繁瑣饶囚。spring提供了一種簡單便捷的模板類來進行操作越锈,這就是RestTemplate绍些。

二.一個簡單的例子炒瘸。

定義一個簡單的restful接口

@RestController
public class TestController
{
    @RequestMapping(value = "testPost", method = RequestMethod.POST)
    public ResponseBean testPost(@RequestBody RequestBean requestBean)
    {
        ResponseBean responseBean = new ResponseBean();
        responseBean.setRetCode("0000");
        responseBean.setRetMsg("succ");

        return responseBean;
    }
}

使用RestTemplate訪問該服務(wù)

        //請求地址
        String url = "http://localhost:8080/testPost";
        //入?yún)?        RequestBean requestBean = new RequestBean();
        requestBean.setTest1("1");
        requestBean.setTest2("2");
        requestBean.setTest3("3");

        RestTemplate restTemplate = new RestTemplate();
        ResponseBean responseBean = restTemplate.postForObject(url, requestBean, ResponseBean.class);

從這個例子可以看出淤堵,使用restTemplate訪問restful接口非常的簡單粗暴無腦(url, requestMap, ResponseBean.class)這三個參數(shù)分別代表 請求地址什燕、請求參數(shù)粘勒、HTTP響應(yīng)轉(zhuǎn)換被轉(zhuǎn)換成的對象類型。

RestTemplate方法的名稱遵循命名約定屎即,第一部分指出正在調(diào)用什么HTTP方法庙睡,第二部分指示返回的內(nèi)容事富。本例中調(diào)用了restTemplate.postForObject方法,post指調(diào)用了HTTP的post方法乘陪,Object指將HTTP響應(yīng)轉(zhuǎn)換為您選擇的對象類型统台。還有其他很多類似的方法,有興趣的同學(xué)可以參考官方api啡邑。

三.手動指定轉(zhuǎn)換器(HttpMessageConverter)

我們知道贱勃,調(diào)用reseful接口傳遞的數(shù)據(jù)內(nèi)容是json格式的字符串,返回的響應(yīng)也是json格式的字符串谤逼。然而restTemplate.postForObject方法的請求參數(shù)RequestBean和返回參數(shù)ResponseBean卻都是java類贵扰。是RestTemplate通過HttpMessageConverter自動幫我們做了轉(zhuǎn)換的操作。

默認情況下RestTemplate自動幫我們注冊了一組HttpMessageConverter用來處理一些不同的contentType的請求流部。
StringHttpMessageConverter來處理text/plain;MappingJackson2HttpMessageConverter來處理application/json;MappingJackson2XmlHttpMessageConverter來處理application/xml戚绕。
你可以在org.springframework.http.converter包下找到所有spring幫我們實現(xiàn)好的轉(zhuǎn)換器。
如果現(xiàn)有的轉(zhuǎn)換器不能滿足你的需求枝冀,你還可以實現(xiàn)org.springframework.http.converter.HttpMessageConverter接口自己寫一個舞丛。詳情參考官方api

選好了HttpMessageConverter后怎么把它注冊到我們的RestTemplate中呢果漾。

        RestTemplate restTemplate = new RestTemplate();
        //獲取RestTemplate默認配置好的所有轉(zhuǎn)換器
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        //默認的MappingJackson2HttpMessageConverter在第7個 先把它移除掉
        messageConverters.remove(6);
        //添加上GSON的轉(zhuǎn)換器
        messageConverters.add(6, new GsonHttpMessageConverter());

這個簡單的例子展示了如何使用GsonHttpMessageConverter替換掉默認用來處理application/jsonMappingJackson2HttpMessageConverter球切。

四.設(shè)置底層連接方式

要創(chuàng)建一個RestTemplate的實例,您可以像上述例子中簡單地調(diào)用默認的無參數(shù)構(gòu)造函數(shù)绒障。這將使用java.net包中的標準Java類作為底層實現(xiàn)來創(chuàng)建HTTP請求吨凑。
但很多時候我們需要像傳統(tǒng)的HttpClient那樣設(shè)置HTTP請求的一些屬性。RestTemplate使用了一種很偷懶的方式實現(xiàn)了這個需求户辱,那就是直接使用一個HttpClient作為底層實現(xiàn)......

        //生成一個設(shè)置了連接超時時間怀骤、請求超時時間、異常最大重試次數(shù)的httpClient
        RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(10000).setConnectTimeout(10000).setSocketTimeout(30000).build();
        HttpClientBuilder builder = HttpClientBuilder.create().setDefaultRequestConfig(config).setRetryHandler(new DefaultHttpRequestRetryHandler(5, false));
        HttpClient httpClient = builder.build();
        //使用httpClient創(chuàng)建一個ClientHttpRequestFactory的實現(xiàn)
        ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
         //ClientHttpRequestFactory作為參數(shù)構(gòu)造一個使用作為底層的RestTemplate
        RestTemplate restTemplate = new RestTemplate(requestFactory);

五.設(shè)置攔截器(ClientHttpRequestInterceptor)

有時候我們需要對請求做一些通用的攔截設(shè)置焕妙,這就可以使用攔截器進行處理。攔截器需要我們實現(xiàn)org.springframework.http.client.ClientHttpRequestInterceptor接口自己寫弓摘。

舉個簡單的例子焚鹊,寫一個在header中根據(jù)請求內(nèi)容和地址添加令牌的攔截器。

public class TokenInterceptor implements ClientHttpRequestInterceptor
{
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException
    {
        //請求地址
        String checkTokenUrl = request.getURI().getPath();
        //token有效時間
        int ttTime = (int) (System.currentTimeMillis() / 1000 + 1800);
        //請求方法名 POST韧献、GET等
        String methodName = request.getMethod().name();
        //請求內(nèi)容
        String requestBody = new String(body);
        //生成令牌 此處調(diào)用一個自己寫的方法末患,有興趣的朋友可以自行g(shù)oogle如何使用ak/sk生成token,此方法跟本教程無關(guān)锤窑,就不貼出來了
        String token = TokenHelper.generateToken(checkTokenUrl, ttTime, methodName, requestBody);
        //將令牌放入請求header中
        request.getHeaders().add("X-Auth-Token",token);

        return execution.execute(request, body);
    }
}

創(chuàng)建RestTemplate實例的時候可以這樣向其中添加攔截器

        RestTemplate restTemplate = new RestTemplate();
        //向restTemplate中添加自定義的攔截器
        restTemplate.getInterceptors().add(new TokenInterceptor());

六.總結(jié)

通過本章的講解璧针,想必讀者初步的了解了如何使用RestTemplate方便快捷的訪問restful接口。其實RestTemplate的功能非常強大渊啰,作者也僅僅學(xué)了點皮毛探橱。如果大家覺得本文有什么地方?jīng)]寫清楚的或者有其他什么想要了解的可以在下方留言申屹,我后續(xù)會盡量在文中進行補充完善。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末隧膏,一起剝皮案震驚了整個濱河市哗讥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胞枕,老刑警劉巖杆煞,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異腐泻,居然都是意外死亡决乎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門派桩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來构诚,“玉大人,你說我怎么就攤上這事窄坦』椒矗” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵鸭津,是天一觀的道長彤侍。 經(jīng)常有香客問我,道長逆趋,這世上最難降的妖魔是什么盏阶? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮闻书,結(jié)果婚禮上名斟,老公的妹妹穿的比我還像新娘。我一直安慰自己魄眉,他們只是感情好砰盐,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坑律,像睡著了一般岩梳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上晃择,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天冀值,我揣著相機與錄音,去河邊找鬼宫屠。 笑死列疗,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的浪蹂。 我是一名探鬼主播抵栈,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼告材,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了竭讳?” 一聲冷哼從身側(cè)響起创葡,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绢慢,沒想到半個月后灿渴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡胰舆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年骚露,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缚窿。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡棘幸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出倦零,到底是詐尸還是另有隱情误续,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布扫茅,位于F島的核電站蹋嵌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏葫隙。R本人自食惡果不足惜栽烂,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望恋脚。 院中可真熱鬧腺办,春花似錦、人聲如沸糟描。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽船响。三九已至磺送,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灿意,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工崇呵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缤剧,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓域慷,卻偏偏與公主長得像荒辕,于是被迫代替她去往敵國和親汗销。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容