亚洲全黄无码一级在线看_国产剧情久久久性色_无码av一区二区三区无码_亚洲成a×人片在线观看

當(dāng)前位置: 首頁(yè) > 科技新聞 >

使用 RestTemplate 進(jìn)行第三方Rest服務(wù)調(diào)用

時(shí)間:2020-06-05 17:39來(lái)源:網(wǎng)絡(luò)整理 瀏覽:
1. 前言RestTemplate 是 Spring 提供的一個(gè)調(diào)用 Restful 服務(wù)的抽象層,它簡(jiǎn)化的同 Restful 服務(wù)的通信方
使用 RestTemplate 進(jìn)行第三方Rest服務(wù)調(diào)用

1. 前言

RestTemplate 是 Spring 提供的一個(gè)調(diào)用 Restful 服務(wù)的抽象層,它簡(jiǎn)化的同 Restful 服務(wù)的通信方式,隱藏了不必要的一些細(xì)節(jié),讓我們更加優(yōu)雅地在應(yīng)用中調(diào)用 Restful 服務(wù) 。但是在 Spring 5.0 以后RestTemplate處于維護(hù)模式,不再進(jìn)行新特性的開發(fā),僅僅進(jìn)行一些日常維護(hù)。Spring 建議我們使用同時(shí)支持同步、異步和 Stream 的另一個(gè) API —— WebClient 。但是在 Spring MVC 下目前我們還沒有更好的選擇。

2. RestTemplate 的使用場(chǎng)景

我們?cè)陧?xiàng)目中經(jīng)常要使用第三方Rest API 服務(wù),比如短信、快遞查詢、天氣預(yù)報(bào)等等。這些第三方只要提供了 Rest Api ,你都可以使用 RestTemplate 來(lái)調(diào)用它們。

3. 初始化 RestTemplate

只要你的項(xiàng)目使用了 Spring MVC 就已經(jīng)集成了RestTemplate 。但是通常情況下該類不會(huì)自動(dòng)被注入 Spring IoC容器,因?yàn)楹芏?Rest API 都具有特殊性,為了更加靈活的進(jìn)行定制,其構(gòu)建類 RestTemplateBuilder被自動(dòng)注入了 Spring IoC 容器。 我們可以這樣初始化它:

package cn.felord.rest.webclient;

import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
* @author felord.cn
* @since 14:58
**/
@Component
public class SomeWeb {

private final RestTemplateBuilder restTemplateBuilder;

public SomeWeb(RestTemplateBuilder restTemplateBuilder) {
this.restTemplateBuilder = restTemplateBuilder;
}

public RestTemplate restTemplate() {
// 通過(guò) builder 定制
return restTemplateBuilder.requestFactory(OkHttp3ClientHttpRequestFactory::new).
build();
}
}

最佳實(shí)踐:針對(duì)每一個(gè)第三方服務(wù)盡量定制對(duì)應(yīng)的 RestTemplate,盡量不公用,除非這些第三方的流程完全一致。

2.1 RestTemplate 底層

默認(rèn)情況下,RestTemplate 使用 java.net.HttpURLConnection 作為實(shí)現(xiàn),一但使用它時(shí)有異常響應(yīng)狀態(tài)(比如 401),就會(huì)引發(fā)異常,因此我們一般不使用它。我們可以切換到 Netty 、Apache HttpComponents、okHttp 默認(rèn)實(shí)現(xiàn)的客戶端庫(kù),參考 2 中的 requestFactory(ClientHttpRequestFactory factory) 接入方法,也可以自行實(shí)現(xiàn) ClientHttpRequestFactory 對(duì)接其它第三方庫(kù)進(jìn)行接入。這里我使用 okHttp 。你可以定制這些第三方庫(kù)提供的特性豐富你的 RestTemplate,比如設(shè)置請(qǐng)求超時(shí)。

3. 常用方法場(chǎng)景舉例

RestTemplate 支持所有 Restful 風(fēng)格方法,你可以根據(jù)需要進(jìn)行選擇,這里我們只介紹一些常用的方法。所有方法都支持URI 模板和 URI 參數(shù),支持下面這種寫法:

# 類似 spring mvc 中的 @PathVariable
https://api.apiopen.top/{method}
3.1 {get|post}ForEntity

Get 請(qǐng)求后將響應(yīng)映射為 ResponseEntity<T> 響應(yīng)對(duì)象,一個(gè)響應(yīng)體的包裝對(duì)象。我們使用下列代碼來(lái)隨機(jī)請(qǐng)求 5 條漂亮小姐姐的照片,你可以打印進(jìn)行查看:

    @Autowired
RestTemplate restTemplate;

void contextLoads() {
String url = "https://api.apiopen.top/getImages?page=0&count=5";
ResponseEntity<String> responseEntity = restTemplate
.getForEntity(url,String.class);
String body = responseEntity.getBody();
System.out.println("body = " + body);
}

上面的方法改為按順序的可變參數(shù):

        String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
ResponseEntity<String> responseEntity = restTemplate
.getForEntity(url,String.class,0,5);
String body = responseEntity.getBody();
System.out.println("body = " + body);

或者使用 Map<String,Object>:

        String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
HashMap<String, Object> uriParams = new HashMap<>();
uriParams.put("page", 0);
uriParams.put("count", 5);
ResponseEntity<String> responseEntity = restTemplate
.getForEntity(url, String.class, uriParams);
String body = responseEntity.getBody();
System.out.println("body = " + body);

post 請(qǐng)求 額外會(huì)傳入一個(gè)可能為 null 的 VO 對(duì)象,或者 MultiValueMap 來(lái)攜帶請(qǐng)求體參數(shù) ,它們最終會(huì)被封裝入

org.springframework.http.HttpEntity 對(duì)象,該對(duì)象可包含以下兩個(gè)部分:

請(qǐng)求體對(duì)象,可使用實(shí)體 VO、MultiValueMap請(qǐng)求頭對(duì)象, org.springframework.http.HttpHeaders
 String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<UserVO> httpEntity = new HttpEntity<>(new UserVO("userName"), headers);
HashMap<String, Object> uriParams = new HashMap<>();
uriParams.put("page", 0);
uriParams.put("count", 5);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class, uriParams);

以上是一個(gè)調(diào)用 Post 請(qǐng)求并攜帶請(qǐng)求體和請(qǐng)求頭的示例。

3.2 {get|post}ForObject

我們還可以將響應(yīng)直接映射到 POJO, 當(dāng)然你需要對(duì)響應(yīng)結(jié)果的結(jié)構(gòu)非常了解,建議先映射到 String 查看一下結(jié)構(gòu)。我們給出一種示例,其他示例參考 3.1 :

        String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
HashMap<String, Object> uriParams = new HashMap<>();
uriParams.put("page", 0);
uriParams.put("count", 5);
String forObject = restTemplate.getForObject(url, String.class, uriParams);
System.out.println("forObject = " + forObject);
3.3 headForHeaders

該方法用于獲取所有的 URI 模板聲明資源的 Header

        String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
HashMap<String, Object> uriParams = new HashMap<>();
uriParams.put("page", 0);
uriParams.put("count", 5);
HttpHeaders httpHeaders = restTemplate.headForHeaders(url, uriParams);
System.out.println(httpHeaders);

結(jié)果為:

[Access-Control-Allow-Headers:"Content-Type, x-requested-with, X-Custom-Header, Authorization", Access-Control-Allow-Methods:"POST, GET, OPTIONS, DELETE", Access-Control-Allow-Origin:"*", Access-Control-Max-Age:"3600", Cache-Control:"private", Content-Length:"608", Content-Type:"application/json;charset=UTF-8", Date:"Tue, 14 Apr 2020 15:25:19 GMT", Expires:"Thu, 01 Jan 1970 00:00:00 GMT"]
3.4 postForLocation

Post 操作不是返回完整的資源,而是返回新創(chuàng)建的資源 URI 。比如上傳文件返回資源的請(qǐng)求路徑。

3.5 put/delete

對(duì)應(yīng) put 請(qǐng)求 和 delete 請(qǐng)求,參考前面的 api。

3.6 optionsForAllow

該方法獲取該 URI 允許的所有請(qǐng)求方法比如 GET、POST、PUT、DELETE 中的一個(gè)或者幾個(gè)。

3.7 exchange

該方法是通用的請(qǐng)求方式,支持 GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE,當(dāng)上面的方式不能滿足你可采用該方式定制,該方式提供了更加靈活的 API,比如你可以定制 GET 方法的請(qǐng)求頭,放入 Jwt Token等操作,這是getForObject 無(wú)法比擬的。

4. 總結(jié)

RestTemplate 是一個(gè)很有用的請(qǐng)求協(xié)調(diào)器,屏蔽了調(diào)用服務(wù)的復(fù)雜度而又不失靈活。但是值得注意的是它正在退出歷史舞臺(tái)。再牛逼的程序員也有轉(zhuǎn)行的那一天不是嗎?

推薦內(nèi)容