Spring?RestTemplate遠(yuǎn)程調(diào)用過(guò)程
Spring RestTemplate遠(yuǎn)程調(diào)用
之前在一個(gè)服務(wù)中調(diào)用另一個(gè)服務(wù)的請(qǐng)求,可以使用UrlConnection類(lèi)來(lái)拼接Http請(qǐng)求頭,這個(gè)時(shí)候就會(huì)發(fā)現(xiàn),很麻煩,使用SpringRestTemplate的話 進(jìn)一步封裝了拼接的代碼,相對(duì)于來(lái)說(shuō)較為便捷。
Spring RestTemplate封裝了http請(qǐng)求,可以較為方便的在一個(gè)服務(wù)中調(diào)用另一個(gè)服務(wù)的請(qǐng)求。
說(shuō)明: 下面的例子是 使用端口為 8075的服務(wù) ,通過(guò)get/id來(lái)遠(yuǎn)程調(diào)用端口8086的服務(wù)的請(qǐng)求。
1、pom.xml加入
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2、調(diào)用服務(wù)中的SpringBoot啟動(dòng)類(lèi)注入RestTemplate
@Bean public RestTemplate restTemplate(){ return new RestTemplate(); }
3、在需要使用的Controller類(lèi)中自動(dòng)導(dǎo)入RestTemplate
@Autowired RestTemplate restTemplate;
4、根據(jù)調(diào)用某服務(wù)的ip拼接 url
調(diào)用RestTemplate的api獲取響應(yīng)內(nèi)容
@RequestMapping("get/{id}") public User getById(@PathVariable("id") Integer id ){ String url = "http://localhost:8086/get/"+id; User s = restTemplate.getForObject(url,User.class); return s; }
5、測(cè)試
調(diào)用成功
5、出現(xiàn)的問(wèn)題和解決
如果使用RestTemplate的話,雖然為我們封裝了http請(qǐng)求頭等信息,但是url需要自己寫(xiě),不夠靈活。
1、如果調(diào)用的服務(wù)是一個(gè)集群呢,固定了ip地址是否不妥,解決方案是使用ribbon,保證多個(gè)服務(wù)集群用的服務(wù)名是一致的,拼接的url 的ip地址用服務(wù)名來(lái)拼接,這個(gè)時(shí)候就可以用一個(gè)url訪問(wèn)多個(gè)端口號(hào)不一樣的相同服務(wù)了,ribbon會(huì)將服務(wù)名轉(zhuǎn)換成可以用的端口號(hào)。但是調(diào)用的服務(wù)有多個(gè),如何來(lái)選擇一個(gè)服務(wù)請(qǐng)求呢?這個(gè)時(shí)候就需要一個(gè)負(fù)載均衡算法,常用的負(fù)載均衡的算法有 輪詢等。
2、用于拼接的http還是感覺(jué)不夠簡(jiǎn)便,還需要自己去拼接,可不可以更加靈活?可以使用feign來(lái)代替RestTemplate,feign是一個(gè)聲明式的遠(yuǎn)程調(diào)用,集成了ribbon和hystrix。
RestTemplate遠(yuǎn)程調(diào)用時(shí)遇到的問(wèn)題
最近公司給了個(gè)任務(wù),讓我跟第三方接口聯(lián)調(diào),正好項(xiàng)目使用的是SpringBoot那我自然而然想到了SpringMVC提供的RestTemplate 來(lái)進(jìn)行遠(yuǎn)程調(diào)用,但是在使用RestTemplate遠(yuǎn)程調(diào)用時(shí)出現(xiàn)了點(diǎn)問(wèn)題…
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
1.引入代碼
代碼如下(示例):
ResponseEntity<String> responseEntity = restTemplate.postForEntity(activityParameterConfig.getPakageProvide() + "?sign=" + sign, jsonValue, String.class); String body = responseEntity.getBody(); System.out.println("body = " + body);
在將結(jié)果轉(zhuǎn)化為String時(shí)成功獲取到了結(jié)果:
body = {"status":100,"msg":"發(fā)送成功","info":{"telphonenum":"*******1272","list":[{"ticketnum":"94330075353","start_use_date":"2021-03-09","end_use_date":"2031-03-09"}],"serial":"fa6b0592741a4d838c6a4737323c0c34","serial_number":"202103091614452220"}}
但是直接轉(zhuǎn)換為String還要再將其轉(zhuǎn)換為DTO,所以索性就選擇直接選擇在RestTemplate封裝結(jié)果時(shí)直接裝換為對(duì)應(yīng)DTO
2.引入代碼
代碼如下(示例):
ResponseEntity<GiftDistributeResDTO> entity = restTemplate.postForEntity(activityParameterConfig.getPakageProvide() + "?sign=" + sign, jsonValue, GiftDistributeResDTO.class); GiftDistributeResDTO distributeResDTO = entity.getBody(); System.out.println("distributeResDTO = " + distributeResDTO);
結(jié)果報(bào)錯(cuò)了…提示沒(méi)有對(duì)應(yīng)的HttpMessageConverter處理類(lèi)型為Content Type [text/html;charset=utf-8]] 的數(shù)據(jù)。
2021-03-09 16:14:47.221 ERROR 13548 --- [nio-8082-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.example.demo.user.dto.GiftDistributeResDTO] and content type [text/html;charset=utf-8]] with root cause
org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.example.demo.user.dto.GiftDistributeResDTO] and content type [text/html;charset=utf-8]
小結(jié)
于是Debug了下發(fā)現(xiàn)RestTemplate中存在7種轉(zhuǎn)換器:
其中將結(jié)果轉(zhuǎn)換為我們要的DTO的是MappingJackson2HttpMessageConverter這個(gè)轉(zhuǎn)換器,再進(jìn)去看看這個(gè)轉(zhuǎn)換器屬性:
結(jié)果發(fā)現(xiàn)這個(gè)轉(zhuǎn)換器所支持的MediaTypes不存在上述text/html這種類(lèi)型,所以才會(huì)報(bào)錯(cuò),既然找到了問(wèn)題那就在創(chuàng)建RestTemplate時(shí)給它多加一些支持的類(lèi)型:
@Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters(); for (HttpMessageConverter<?> httpMessageConverter : converters) { if(httpMessageConverter instanceof MappingJackson2HttpMessageConverter){ ArrayList<MediaType> mediaTypes = new ArrayList<>(); mediaTypes.add(MediaType.ALL); ((MappingJackson2HttpMessageConverter) httpMessageConverter).setSupportedMediaTypes(mediaTypes); } } return restTemplate; }
再次調(diào)試發(fā)現(xiàn)結(jié)果已經(jīng)可以正常封裝到我們需要的DTO了:
distributeResDTO = GiftDistributeResDTO(status=100, msg=發(fā)送禮包成功!, info=GiftDistributeInfo(telphonenum=*******1272, serial_number=202103091641391875, serial=27c66dbdce6a476481e895b852d82fd3, list=[GiftDistributeList(ticketnum=94330070661, start_use_date=2021-03-09, end_use_date=2031-03-09)]), url=null)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
ObjectInputStream 和 ObjectOutputStream 介紹_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
ObjectInputStream 和 ObjectOutputStream 的作用是,對(duì)基本數(shù)據(jù)和對(duì)象進(jìn)行序列化操作支持。本文給大家詳細(xì)介紹了ObjectInputStream 和 ObjectOutputStream的相關(guān)知識(shí),感興趣的朋友一起學(xué)習(xí)吧2017-05-05Spring和Spring?Boot的區(qū)別及說(shuō)明
這篇文章主要介紹了Spring和Spring?Boot的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04Java9版本新特性同一個(gè)Jar支持多JDK版本運(yùn)行
這篇文章主要為大家介紹了Java9新版本的特性之同一個(gè)Jar支持多JDK版本運(yùn)行的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03Java實(shí)現(xiàn)五子棋的基礎(chǔ)方法
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)五子棋的基礎(chǔ)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09解讀@Scheduled任務(wù)調(diào)度/定時(shí)任務(wù)非分布式
這篇文章主要介紹了解讀@Scheduled任務(wù)調(diào)度/定時(shí)任務(wù)非分布式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08Maven插件構(gòu)建Docker鏡像的實(shí)現(xiàn)步驟
這篇文章主要介紹了Maven插件構(gòu)建Docker鏡像的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10Spring Boot引入swagger-ui 后swagger-ui.html無(wú)法訪問(wèn)404的問(wèn)題
這篇文章主要介紹了Spring Boot引入swagger-ui 后swagger-ui.html無(wú)法訪問(wèn)404的問(wèn)題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09IDEA 如何控制編輯左側(cè)的功能圖標(biāo)ICON(操作步驟)
很多朋友被idea左側(cè)的圖標(biāo)不見(jiàn)了這一問(wèn)題搞的焦頭爛額,不知道該怎么操作,今天小編就交大家如何控制編輯左側(cè)的功能圖標(biāo) ICON,文字內(nèi)容不多,主要通過(guò)兩張截圖給大家說(shuō)明,感興趣的朋友一起看看吧2021-05-05微服務(wù)領(lǐng)域Spring Boot自動(dòng)伸縮的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于微服務(wù)領(lǐng)域Spring Boot自動(dòng)伸縮的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10