javascript
spring resttemplate 中文参数_SpringBoot使用RestTemplate访问第三方接口
養成習慣,先贊后看!!!
前言
相信大家都知道如何在自己的項目里面調用自己的接口,只需要調用自己項目里面接口特定的URL地址就行了,但是如果是調用其他項目的接口呢,這時候如果是直接調用的話,很明顯我們是不能夠調用的.肯定是要通過某個工具才能夠進行訪問的.我們可以通過下面這張圖來理解.
在這里插入圖片描述介紹
HTTPClient與RestTemplate
在RestTemplate出現之前,一般都是通過HTTPClient進行訪問,但是HTTPClient訪問又十分的麻煩,這里貼一個樣例讓大家先感受 一下HTTPClient整個的請求方式
@Test????public?String?test()?throws?ClientProtocolException,?IOException?{
????????//1、創建httpClient
????????CloseableHttpClient?client?=?HttpClients.createDefault();
????????//2、封裝請求參數
????????List?list?=?new?ArrayList();//這里默認都是String,String,但是之后會對相應的數據類型進行轉換
????????list.add(new?BasicNameValuePair("username",?"name"));//3、轉化參數
????????String?params?=?EntityUtils.toString(new?UrlEncodedFormEntity(list,?Consts.UTF_8));//4、創建HttpGet請求
????????HttpGet?httpGet?=?new?HttpGet("url接口地址"+"?"+params);
????????CloseableHttpResponse?response?=?client.execute(httpGet);//5、獲取實體
????????HttpEntity?entity?=?response.getEntity();//將實體裝成字符串
????????String?string?=?EntityUtils.toString(entity);
????????response.close();return?result;
????}
其實整體邏輯還是比較清晰的就是整體的代碼量比較多,使得代碼比較的臃腫,之后推出了RestTemplate之后,將訪問接口的代碼極度減少,更加方便我們的使用,這里我們使用RestTemplate之后看看上述的接口我們編寫需要什么樣的步驟.
?@Test????public?String?test()??{
?????????HashMap?map?=?new?HashMap<>();
?????????map.put("typeId",1);//三個參數分別為??接口地址,返回數據類型,參數列表
?????????String?result=?restTemplate.getForObject("url接口地址",?String.class,?map);return?result;
????}
不對比的話,我們還覺得httpclient還是比較好用的,但是對比完之后我們就可以發現,httpclient是個啥啊,這代碼量搞得只剩原來的約三分之一.
在這里插入圖片描述并且相對來說RestTemplate也極度的減少了流程代碼,是的我們只需要專注于核心的流程業務即請求接口地址是啥,請求的參數是什么這兩個最最最重要的步驟,其他的客戶端的創建,請求參數轉換,連接關閉這些都不需要我們再考慮,著實方便了我們的開發.使用
既然我們已經比較完了,那么我們就要來看看我們到底應該如何使用RestTemplate了.
第一步-注入bean
既然我們想使用RestTemplate,那么我們就必須要將RestTemplate注入到Spring容器之中,所以我們在啟動類中注入我們的RestTemplate
@Bean?//必須new?一個RestTemplate并放入spring容器當中,否則啟動時報錯????public?RestTemplate?restTemplate()?{
????????RestTemplate?restTemplate?=?new?RestTemplate();
????????HttpComponentsClientHttpRequestFactory?httpRequestFactory?=?new?HttpComponentsClientHttpRequestFactory();
????????httpRequestFactory.setConnectionRequestTimeout(30?*?1000);
????????httpRequestFactory.setConnectTimeout(30?*?3000);
????????httpRequestFactory.setReadTimeout(30?*?3000);
????????restTemplate.setRequestFactory(httpRequestFactory);
????????return?restTemplate;
????}
這樣我們就能夠正常的使用RestTemplate
第二步-調用方法
這里我們就可以在我們需要調用第三方接口的controller里面注入我們RestTemplate了
?@Autowired?RestTemplate?restTemplate;
這時候我們來看看restTemplate都有哪些方法也可以理解為他有哪些請求第三方接口的方法
首先我們可以先看到Get請求有這么些方法
Post請求有這么些方法
在這里插入圖片描述這么些方法其實就夠我們用了.
getForEntity與getForObject的區別
接下來我們就來分析一下源碼,看看這些方法都有什么樣的區別,這里以 get請求 為例,post請求類似,大家可以自行查閱
其實方法主要分為 兩大類 一類就是 getForEntity ,另外一類就是 getForObject
我們首先區分提下這兩個大類的區別,這里我們將兩段代碼貼出來對比著看
首先我們來看 第一個不同 的地方:
我們首先可以看到就是兩者的 返回類型是不一樣 的,我們可以看到getForEntity的返回類型是規定死的,只能是responseEntity,但是responseEntity里面包含的數據是可以變化的,getForObject的返回類型則是可以變化的,也就是自定義的意思.
接著我們來看第二個不同的地方:
在這里插入圖片描述getForObject相對于getForEntity來說,多了一步類型轉換的步驟,其實可以理解成getForObject對getForEntity獲得的數據進行了 更深層次的一次封裝 ,只讓用戶注重于他們所注重的數據本身,將其他一些無關緊要的數據,比如說 請求頭,響應狀態 這些數據全部都隱藏起來,只讓用戶看到他們想要的數據,就比如說查出來的信息
說了這么些不同,還是用一個例子來幫助大家更好的理解這兩點不同吧.同樣都是查詢某一個信息集合
我們先通過 getForEntity 實現看一下
@GetMapping("/testRestTemplate")@ApiOperation("測試RestTemplate")
@Scheduled(fixedRate?=?5000)
public?ApiResult?testRestTemplate()?throws?ClientProtocolException,?IOException{
????HashMap?map?=?new?HashMap<>();
????map.put("typeId",1);
????ResponseEntity?responseEntity=restTemplate.getForEntity("接口地址",?String.class,?map);
????String?boby=responseEntity.getBody();
????JSONObject?jsonObject?=?JSONObject.parseObject(boby);
????List?alertInfoByTypeIdList=?(List)?jsonObject.get("data");
????System.out.println("*****************************************************");
????System.out.println("當前時間:"+?LocalTime.now());
????System.out.println(responseEntity);
????System.out.println(boby);
????System.out.println(alertInfoByTypeIdList);return?ApiResult.ok(alertInfoByTypeIdList);
}
我們來看看運行之后的結果:
在這里插入圖片描述首先我們先來看打印出來的最原始的responseEntity數據在這里插入圖片描述
包含了我們需要的數據以及響應狀態以及請求頭等各種信息
如下圖所示,可以獲取到如下的信息.在這里插入圖片描述
接著我們再來看看responseEntity的主體數據boby數據
在這里插入圖片描述我們明顯看到這就是responseEntity數據中的一部分
最后我們alertInfoByTypeIdList數據,這部分數據是我們已經通過JSONObject將body數據解析完成之后的樣子
在這里插入圖片描述可以看到數據已經是正經的json格式了.
接下來我們在對比一下通過 getForObject 實現之后的效果:
@GetMapping("/testRestTemplate")@ApiOperation("測試RestTemplate")
@Scheduled(fixedRate?=?5000)
public?ApiResult?testRestTemplate()?throws?ClientProtocolException,?IOException{
????HashMap?map?=?new?HashMap<>();
????????map.put("typeId",1);
????????String?result=?restTemplate.getForObject("接口地址",?String.class,?map);
????????JSONObject?jsonObject?=?JSONObject.parseObject(result);
????????List?alertInfoByTypeIdList=?(List)?jsonObject.get("data");
????????System.out.println("*****************************************************");
????????System.out.println("當前時間:"+?LocalTime.now());
????????System.out.println(result);
????????System.out.println(alertInfoByTypeIdList);return?ApiResult.ok(alertInfoByTypeIdList);
}
我們來看看打印后的結果:
在這里插入圖片描述這里我們先來看一下最原始的返回數據result,可以看到數據就是我們原來定義好的返回類型在這里插入圖片描述
不再包含那些雜七雜八的數據了.
之后我們再來看一下通過JSONObject解析之后的數據
在這里插入圖片描述可以看到也已經是正經的json的數據格式了.
通過上面的對比之后我們能夠發現,getForObject相對來說能夠更加友好的將我們需要的數據傳輸過來,畢竟已經 對getForEntity傳輸過來的數據進行了一次封裝了 .并且再拋出了打印這些代碼后,我們能夠發現整體的代碼也變得更加的 簡潔 .
get請求下的方法比較
這里我們就拿 get請求 來舉例,post類似,大家可以自行查看.
其實當我們看到getForEntity的三個重載方法的時候我們就能知道他們只是 請求參數有所不同 ,并且主要不同的參數就是第三個參數,接下來我們詳細說一下.
`getForEntity(String url, ClassresponseType, Object… uriVariables)`
????public??ResponseEntity?getForEntity(String?url,?Class?responseType,?Object...?uriVariables)throws?RestClientException?{
????????RequestCallback?requestCallback?=?acceptHeaderRequestCallback(responseType);
????????ResponseExtractor>?responseExtractor?=?responseEntityExtractor(responseType);return?nonNull(execute(url,?HttpMethod.GET,?requestCallback,?responseExtractor,?uriVariables));
????}
我們看到Object的時候我們就能知道,如果請求的時候,請求參數是我們所定義的一個對象的話,那么我們就可以運用該接口,比如說我們執行新增某個對象的時候我們就可以使用該方法,舉例如下:
User?user=new?User();String?result=?restTemplate.getForObject("接口地址",?String.class,?user);
`getForEntity(String url, ClassresponseType, MapuriVariables)`
????public??ResponseEntity?getForEntity(String?url,?Class?responseType,?Map?uriVariables)throws?RestClientException?{
????????RequestCallback?requestCallback?=?acceptHeaderRequestCallback(responseType);
????????ResponseExtractor>?responseExtractor?=?responseEntityExtractor(responseType);return?nonNull(execute(url,?HttpMethod.GET,?requestCallback,?responseExtractor,?uriVariables));
????}
該方法就用于我們請求的時候需要傳入參數,但是這個參數并不屬于我們所創建的任何對象,可能只是單單幾個參數,就好比我們登陸,我們就需要傳給后臺username和password,我們不可能單獨為了這兩個參數在創建一個對象的,所以在這種情況下我們可以使用該方法.并且這里支持我們使用 HashMap 不像httpclient那樣只支持 HashMap 這就使得我們可以直接定義數據的類型,不需要像httpclient那樣還需要多一步數據類型轉換的步驟,更加的方便.
舉例如下:
map.put("userId",2293557957);
map.put("password","1234567");
String?result=?restTemplate.getForObject("接口地址",?String.class,?map);
`getForEntity(URI url, ClassresponseType)`
????public??ResponseEntity?getForEntity(URI?url,?Class?responseType)?throws?RestClientException?{
????????RequestCallback?requestCallback?=?acceptHeaderRequestCallback(responseType);
????????ResponseExtractor>?responseExtractor?=?responseEntityExtractor(responseType);return?nonNull(execute(url,?HttpMethod.GET,?requestCallback,?responseExtractor));
????}
這種很明顯就是我們直接發請求,并不需要我們帶任何參數,就好比我們需要獲取所有的用戶,我們只需要請求該接口,獲取所有的用戶數據就行了,并不需要我們在傳入任何的參數.
舉例如下:
上面的講完之后我們就可以類比到getForObject里面,邏輯其實是一樣的.
`getForObject(String url, ClassresponseType, Object… uriVariables)`
????@Nullable
????public??T?getForObject(String?url,?Class?responseType,?Object...?uriVariables)?throws?RestClientException?{
????????RequestCallback?requestCallback?=?acceptHeaderRequestCallback(responseType);
????????HttpMessageConverterExtractor?responseExtractor?=new?HttpMessageConverterExtractor<>(responseType,?getMessageConverters(),?logger);return?execute(url,?HttpMethod.GET,?requestCallback,?responseExtractor,?uriVariables);
????}
`getForObject(String url, ClassresponseType, MapuriVariables)`
????@Nullable
????public??T?getForObject(String?url,?Class?responseType,?Map?uriVariables)?throws?RestClientException?{
????????RequestCallback?requestCallback?=?acceptHeaderRequestCallback(responseType);
????????HttpMessageConverterExtractor?responseExtractor?=new?HttpMessageConverterExtractor<>(responseType,?getMessageConverters(),?logger);return?execute(url,?HttpMethod.GET,?requestCallback,?responseExtractor,?uriVariables);
????}???
`getForObject(URI url, ClassresponseType)`
????@Nullable
????public??T?getForObject(URI?url,?Class?responseType)?throws?RestClientException?{
????????RequestCallback?requestCallback?=?acceptHeaderRequestCallback(responseType);
????????HttpMessageConverterExtractor?responseExtractor?=new?HttpMessageConverterExtractor<>(responseType,?getMessageConverters(),?logger);return?execute(url,?HttpMethod.GET,?requestCallback,?responseExtractor);
????}???
這樣我們使用RestTemplate訪問第三方接口就完成了.
第三步-配置字符集,解決亂碼
但是還需要注意一點,如果我們請求回來的數據里面包含中文的話,那么我們就需要重新配置一下字符集,否則中文是會亂碼的,就如下圖所示:
在這里插入圖片描述在我們注入的的RestTemplate添加下面這段修改字符集的代碼:?@Bean?//必須new?一個RestTemplate并放入spring容器當中,否則啟動時報錯
????public?RestTemplate?restTemplate()?{
????????RestTemplate?restTemplate?=?new?RestTemplate();
????????HttpComponentsClientHttpRequestFactory?httpRequestFactory?=?new?HttpComponentsClientHttpRequestFactory();
????????httpRequestFactory.setConnectionRequestTimeout(30?*?1000);
????????httpRequestFactory.setConnectTimeout(30?*?3000);
????????httpRequestFactory.setReadTimeout(30?*?3000);
//????????//修改字符集
????????List>?list?=?restTemplate.getMessageConverters();for?(HttpMessageConverter>?httpMessageConverter?:?list)?{if?(httpMessageConverter?instanceof?StringHttpMessageConverter){
????????????????((StringHttpMessageConverter)
????????????????????????httpMessageConverter).setDefaultCharset(Charset.forName("utf-8"));break;
????????????}
????????}
????????restTemplate.setRequestFactory(httpRequestFactory);return?restTemplate;
????}在這里插入圖片描述
都看到這兒了,如果覺得對你有幫助的話,可以關注我的公眾號,新人up需要你的支持!!!
在這里插入圖片描述總結
以上是生活随笔為你收集整理的spring resttemplate 中文参数_SpringBoot使用RestTemplate访问第三方接口的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c mysql 关闭连接池_数据库连接
- 下一篇: 腾讯在线人数统计_PHP + REDIS