Spring?RestTemplate遠程調(diào)用過程
Spring RestTemplate遠程調(diào)用
之前在一個服務中調(diào)用另一個服務的請求,可以使用UrlConnection類來拼接Http請求頭,這個時候就會發(fā)現(xiàn),很麻煩,使用SpringRestTemplate的話 進一步封裝了拼接的代碼,相對于來說較為便捷。
Spring RestTemplate封裝了http請求,可以較為方便的在一個服務中調(diào)用另一個服務的請求。
說明: 下面的例子是 使用端口為 8075的服務 ,通過get/id來遠程調(diào)用端口8086的服務的請求。
1、pom.xml加入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>2、調(diào)用服務中的SpringBoot啟動類注入RestTemplate

@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}3、在需要使用的Controller類中自動導入RestTemplate

@Autowired
RestTemplate restTemplate;4、根據(jù)調(diào)用某服務的ip拼接 url
調(diào)用RestTemplate的api獲取響應內(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、測試
調(diào)用成功

5、出現(xiàn)的問題和解決
如果使用RestTemplate的話,雖然為我們封裝了http請求頭等信息,但是url需要自己寫,不夠靈活。
1、如果調(diào)用的服務是一個集群呢,固定了ip地址是否不妥,解決方案是使用ribbon,保證多個服務集群用的服務名是一致的,拼接的url 的ip地址用服務名來拼接,這個時候就可以用一個url訪問多個端口號不一樣的相同服務了,ribbon會將服務名轉換成可以用的端口號。但是調(diào)用的服務有多個,如何來選擇一個服務請求呢?這個時候就需要一個負載均衡算法,常用的負載均衡的算法有 輪詢等。
2、用于拼接的http還是感覺不夠簡便,還需要自己去拼接,可不可以更加靈活?可以使用feign來代替RestTemplate,feign是一個聲明式的遠程調(diào)用,集成了ribbon和hystrix。
RestTemplate遠程調(diào)用時遇到的問題
最近公司給了個任務,讓我跟第三方接口聯(lián)調(diào),正好項目使用的是SpringBoot那我自然而然想到了SpringMVC提供的RestTemplate 來進行遠程調(diào)用,但是在使用RestTemplate遠程調(diào)用時出現(xià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);在將結果轉化為String時成功獲取到了結果:
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"}}
但是直接轉換為String還要再將其轉換為DTO,所以索性就選擇直接選擇在RestTemplate封裝結果時直接裝換為對應DTO
2.引入代碼
代碼如下(示例):
ResponseEntity<GiftDistributeResDTO> entity = restTemplate.postForEntity(activityParameterConfig.getPakageProvide() + "?sign=" + sign, jsonValue, GiftDistributeResDTO.class);
GiftDistributeResDTO distributeResDTO = entity.getBody();
System.out.println("distributeResDTO = " + distributeResDTO);結果報錯了…提示沒有對應的HttpMessageConverter處理類型為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]
小結
于是Debug了下發(fā)現(xiàn)RestTemplate中存在7種轉換器:

其中將結果轉換為我們要的DTO的是MappingJackson2HttpMessageConverter這個轉換器,再進去看看這個轉換器屬性:

結果發(fā)現(xiàn)這個轉換器所支持的MediaTypes不存在上述text/html這種類型,所以才會報錯,既然找到了問題那就在創(chuàng)建RestTemplate時給它多加一些支持的類型:
@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)結果已經(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)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Eclipse+Java+Swing+Mysql實現(xiàn)電影購票系統(tǒng)(詳細代碼)
這篇文章主要介紹了Eclipse+Java+Swing+Mysql實現(xiàn)電影購票系統(tǒng)并附詳細的代碼詳解,需要的小伙伴可以參考一下2022-01-01

