成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

RestTemplate-創(chuàng)新互聯(lián)

RestTemplate

General 1920x1080 Gordon Zuchhold (Artstation) digital art science fiction pixel art city cyberpunk animation futuristic city ArtStation artwork futuristic

成都創(chuàng)新互聯(lián)專業(yè)IDC數(shù)據(jù)服務器托管提供商,專業(yè)提供成都服務器托管,服務器租用,川西大數(shù)據(jù)中心,川西大數(shù)據(jù)中心,成都多線服務器托管等服務器托管服務。簡介
  • RestTemplate是由Spring框架提供的一個可用于應用中調用rest服務的類它簡化了與http服務的通信方式,統(tǒng)一了RESTFul的標準,封裝了http連接,我們只需要傳入url及其返回值類型即可。相較于之前常用的HttpClient,RestTemplate是一種更為優(yōu)雅的調用RESTFul服務的方式。
  • Spring應用程序中訪問第三方REST服務與使用Spring RestTemplate類有關。RestTemplate類的設計原則與許多其他Spring的模板類(例如JdbcTemplate)相同,為執(zhí)行復雜任務提供了一種具有默認行為的簡化方法。
  • RestTemplate默認依賴JDK提供了http連接的能力(HttpURLConnection),如果有需要的話也可以通過setRequestFactory方法替換為例如Apache HttpCompoent、Netty或OKHttp等其他Http libaray
  • 考慮到了RestTemplate類是為了調用REST服務而設計的,因此它的主要方法與REST的基礎緊密相連就不足為奇了,后者時HTTP協(xié)議的方法:HEAD、GET、POST、PUT、DELETE、OPTIONS例如,RestTemplate類具有headForHeaders()、getForObject()、putForObject(),put()和delete()等方法。
創(chuàng)建RestTemplate

? 因為RestTemplateSpirng框架提供的所以只要是一個Springboot項目就不用考慮導包的問題,這些都是提供好的。

? 但是Spring并沒有將其加入SpringBean容器中,需要我們手動加入,因為我們首先創(chuàng)建一個Springboot配置類,再在配置類中將我們的RestTemlate注冊到Bean容器中

方法一

? 使用Springboot提供的RestTemplateBuilder構造類來構造一個RestTemplate,可以自定義一些連接參數(shù),如:連接超時時間,讀取超時時間,還有認證信息等

image-20220415202710768

@Configuration
public class WebConfiguration {@Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){return builder
                //設置連接超時時間
                .setConnectTimeout(Duration.ofSeconds(5000))
                //設置讀取超時時間
                .setReadTimeout(Duration.ofSeconds(5000))
                //設置認證信息
                .basicAuthentication("username","password")
                //設置根路徑
                .rootUri("https://api.test.com/")
                //構建
                .build();
    }
}
添加自定義的攔截器

? 自定義攔截器示例

@Slf4j
public class CustomClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {@Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {//打印請求明細
        logRequestDetails(request,body);
        ClientHttpResponse response = execution.execute(request, body);
        //打印響應明細
        logResponseDetails(response);
        
        return response;
    }

    private void logRequestDetails(HttpRequest request, byte[] body){log.debug("Headers:{}",request.getHeaders());
        log.debug("body:{}",new String(body, StandardCharsets.UTF_8));
        log.debug("{}:{}",request.getMethod(),request.getMethodValue());
    }

    private void logResponseDetails(ClientHttpResponse response) throws IOException {log.debug("Status code : {}",response.getStatusCode());
        log.debug("Status text : {}",response.getStatusText());
        log.debug("Headers : {}",response.getHeaders());
        log.debug("Response body: {}", StreamUtils.copyToString(response.getBody(),StandardCharsets.UTF_8));
    }
}

? 使用RestTemplateBuilder構造類,添加自定義攔截器,構造帶有自定義攔截器的RestTemplate實例

@Configuration
public class WebConfiguration {@Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){return builder
                .additionalInterceptors(new CustomClientHttpRequestInterceptor())
                //構建
                .build();
    }    
}

? 測試請求確實經(jīng)過了攔截器,注冊成功(注意請求和響應的流只會被讀取一次,這里我們讀取了response后返回的response就讀取不到剛剛讀過的內(nèi)容了)

?image-20220415204816204


方法二

? 使用RestTemplate構造方法構造一個RestTemlate,雖然不能像RestTemplate構造類那樣更詳細、更多樣的配置參數(shù),但是RestTemplate構造方法在一般情況是夠用的。

image-20220415195208601

  • 無參構造 全部參數(shù)默認
  • 指定ClientHttpRequestFactory的構造方法可以指定自己實現(xiàn)的ClientHttpRequestFactory(客戶端http請求工廠)其他的與無參構造相同。
    • ClientHttpRequestFactory
  • 指定List>的構造方法可以指定自己是實現(xiàn)的HttpMessageConverterHttp消息轉換器)傳入其他與無參構造相同。
@Configuration
public class WebConfiguration {@Bean
    public RestTemplate restTemplate(){return new RestTemplate();
    }
    
}

? 兩者方法都可使用,前者提供了多樣的自定義參數(shù)的選擇,可以將RestTemplate配置的更為完善,后者則簡化了配置雖然配置多樣性不如前者,但是日常使用調用些API還是足以使用

RestTemplate API使用

? 在使用RestTemplate前先讓我們看看RestTemplate有哪些API

image-20220415205801633image-20220415205831801

? 相信大家看到這么多方法,一定很頭大,但是我們仔細看上述的方法,我們可以提取出主要的幾種方法是(這里只討論Http請求的):

  • GET
  • POST
  • PUT
  • DELETE
  • HEAD
  • OPTIONS
  • EXCHANGE
  • EXECUTE

? 這里我給大家安利一個一個網(wǎng)站,它提供免費的RESTFul api的樣例測試。httpbin A simple HTTP Request & Response Service.


GET

? 通過上圖我們可以發(fā)現(xiàn)RestTemlate發(fā)送GET請求的方法有兩種

  • publicT getForObject(...)
  • publicResponseEntitygetForEntity(...)
getForEntity()

? 后綴帶有Entity的方法都代表返回一個ResponseEntity,ResponseEntity是Spring對HTTP請求響應的封裝,包括了幾個重要的元素,如響應碼,contentType、contentLength、響應消息體等

image-20220415211830207

? 通過它繼承父類(HttpEntity)的getHeader()方法我們可以獲取contentType、contentLength、響應消息體等。比如下面這個例子。

public void queryWeather() {ResponseEntityforEntity = restTemplate.getForEntity("https://restapi.amap.com/v3/weather/weatherInfo?city=510100&key=e7a5fa943f706602033b6b329c49fbc6", Object.class);
        System.out.println("狀態(tài)碼:"+forEntity.getStatusCode());
        System.out.println("狀態(tài)碼內(nèi)容:"+forEntity.getStatusCodeValue());
        HttpHeaders headers = forEntity.getHeaders();
        System.out.println("響應頭:"+headers);
        Object body = forEntity.getBody();
        System.out.println("響應內(nèi)容:"+body);
    }

? 該例子中getForEntity()方法的第一個參數(shù)為我要調用服務的URL,第二個參數(shù)則為響應內(nèi)容的類的類型(Java嘛 萬物皆對象)還可以添加第三個參數(shù),第三個參數(shù)為一個可變參數(shù) 代表著調用服務時的傳參。

image-20220415212800839第三個參數(shù)可以使用key-value的map來傳入?yún)?shù)

? get請求也可通過向在url上添加查詢參數(shù)來發(fā)送帶有請求的參數(shù)


getForObject()

? 相比于前者getForEntity()該方法則是,更偏向于直接獲取響應內(nèi)容的,因為他直接返回響應實體的body(響應內(nèi)容),。比如下面這個例子

public void queryWeather() {
        Object body = restTemplate.getForObject("https://restapi.amap.com/v3/weather/weatherInfo?city=510100&key=e7a5fa943f706602033b6b329c49fbc6", Object.class);
        System.out.println(body);
    }
方法參數(shù)簽名與`getForEntity()`基本一致。

? 當你只需要返回的響應內(nèi)容時,使用getForObject()是一個很好的選擇,但當你需要獲得更詳細的響應信息,如響應頭中的信息,你就只能選擇getForEntity()了。


POST

?POST請求有如下三種方法

  • public URI postForLocation(...)
  • publicT postForObject(...)
  • publicResponseEntitypostForEntity(...)

? 后兩種用法與GET基本一致不做詳細介紹,這里著重介紹postForLocation()


postForEntity()

? 該方法有三個參數(shù),第一個為調用服務的地址(URL)

? 第二個參數(shù)表示上傳的參數(shù)(json格式提交)

? 第三個表示返回響應內(nèi)容的具體類型

? 第四個參數(shù)也用于指定參數(shù)(在URL中添加)

@Override
    public void queryWeather() {User user = new User();
        user.setName("魯大師");
        ResponseEntityobjectResponseEntity = restTemplate.postForEntity("https://restapi.amap.com/v3/weather/weatherInfo?city=510100&key=e7a5fa943f706602033b6b329c49fbc6", user, Object.class);
        System.out.println("消息響應內(nèi)容:"+objectResponseEntity.getBody());
    }
postForObject()

? 使用方法與getForObject類似只是多了一個傳入對象參數(shù)(傳入方式與postForEntity()相同)

public void queryWeather() {User user = new User();
        user.setName("魯大師");
        ResponseEntityobjectResponseEntity = restTemplate.postForEntity("https://httpbin.org/post", user, Object.class);
        MediaType contentType = objectResponseEntity.getHeaders().getContentType();
        System.out.println(contentType);
        System.out.println("消息響應內(nèi)容:"+objectResponseEntity.getBody());
    }
postForLocation()

?postForLocation傳參用法與前兩者一致,只不過返回從實體變成了一個URL,因此它不需要指定返回響應內(nèi)容的類型。

public void queryWeather() {User user = new User();
        user.setName("魯大師");
        URI uri = restTemplate.postForLocation("https://httpbin.org/post", user);
        System.out.println(uri);
    }

這個只需要服務提供者返回一個 URI 即可,該URI返回值體現(xiàn)的是:用于提交完成數(shù)據(jù)之后的頁面跳轉,或數(shù)據(jù)提交完成之后的下一步數(shù)據(jù)操作URI。

使用POST以表單方式提交

? 這里我們著重說一下,如何自己封裝一個請求體。

? 我們需要用到如下幾個類

  • HttpHeaders
  • MultiValueMap
  • HttpEntity
HttpHeaders

? 故名思意,就是用來封裝Http請求的請求頭的,這里我們要設置他的ContentType為**MediaType.APPLICATION_FORM_URLENCODED**以使得我們提交的參數(shù)是以Form(表單)的形式提交。

//設置請求頭, x-www-form-urlencoded格式的數(shù)據(jù)
        HttpHeaders httpHeaders = new HttpHeaders();
        //這里指定參數(shù)以UTF-8編碼格式傳輸
        MediaType mediaType = new MediaType(MediaType.APPLICATION_FORM_URLENCODED, UTF_8);
        httpHeaders.setContentType(mediaType);
        //提交參數(shù)設置
        MultiValueMapmap = new LinkedMultiValueMap<>();
        map.add("name","魯大師");

MultiValueMap

? 該類是用來封裝請求參數(shù)的,是以key-value的形式封裝但是以單個key對應多個value的格式傳輸(也就是是以單個key:[value...]的格式傳輸?shù)?。

//提交參數(shù)設置
        MultiValueMapmap = new LinkedMultiValueMap<>();
        map.add("name","魯大師");

? 如果像傳輸單個key對應單個value使用普通的Map傳參即可


HttpEntity

? 該類是用來封裝請求的,主要作用就是將請求頭和請求體封裝在一起成為一個請求實體 T用來指定用來封裝參數(shù)的容器的類型。

//組裝請求體
        HttpEntity>request = new HttpEntity<>(map, httpHeaders);

測試

通過上述介紹后,我們就可以自己封裝一個以form形式提交參數(shù)的POST請求了。

@Test
    void contextLoads() {//請求地址
        String url = "https://httpbin.org/post";

        //設置請求頭, x-www-form-urlencoded格式的數(shù)據(jù)
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        //提交參數(shù)設置
        MultiValueMapmap = new LinkedMultiValueMap<>();
        map.add("name","魯大師");

        //組裝請求體
        HttpEntity>request = new HttpEntity<>(map, httpHeaders);


        //發(fā)送post請求并打印結果 以String類型接收響應結果JSON字符串
        String s = restTemplate.postForObject(url, request, String.class);
        System.out.println(s);
    }

image-20220416124128856

? 通過攔截器攔截了請求并對請求頭進行拆包,可以發(fā)現(xiàn)ContentType已經(jīng)被修改成了x-www-form-urlencoded格式了。

PUT

?PUT請求的方法只有一類

  • void put()
PUT()

? 使用方法與postForEntity()參數(shù)基本一致,只是put方法沒有返回值(也就不必去設置響應內(nèi)容的類型了)。

@Test
    void contextLoads() {//請求地址
        String url = "http://httpbin.org/put";
        User user = new User();
        user.setName("魯大師");
        restTemplate.put(url,user);
    }

DELETE

? 與PUT一樣,DELETE方法只有一類

  • void delete()
delete()

?delete()可以指定url中的中的參數(shù),但是RestTemplatedelete()方法是不支持上傳requestBody的。

void contextLoads() {//請求地址
    String url = "http://httpbin.org/delete";
    restTemplate.delete(url);
}

HEADER

?HEADER也只有一類方法

  • public HttpHeaders headForHeaders()

? 主要用來發(fā)送請求獲取響應頭部信息,但是像DELETE、PUT這類沒有響應的方法,是不能使用該方法的(因為沒有響應也就沒有響應頭了)。

@Test
    void contextLoads() {//請求地址
        String url = "http://httpbin.org/get";
        HttpHeaders httpHeaders = restTemplate.headForHeaders(url);
        System.out.println(httpHeaders);
    }

image-20220416151836372


OPTIONS
  • public SetoptionsForAllow()

? 該方法的主要用來判斷該服務地址,能夠使用那種方法去執(zhí)行

@Test
    void contextLoads() {//請求地址
        String url = "http://httpbin.org/get";
        SethttpMethods = restTemplate.optionsForAllow(url);
        System.out.println(httpMethods);
    }

image-20220416152755753


EXCHANGE
  • ResponseEntityexchange()

? 該接口與其他接口不同

  • 該方法允許用戶指定請求的方法(get,post,put等)
  • 可以在請求中增加body以及頭信息,其內(nèi)容通過參數(shù)HttpEntityrequestEntity描述
  • exchange支持’含參數(shù)的類型(即泛型)'作為返回類型,該特性通過ParameterizedTypeReferenceresponseType描述

? 該方法支持五個參數(shù)

  • 第一個是服務地址
  • 第二個是請求方法
  • 第三個是寫入的請求實體
  • 第四個是響應內(nèi)容的類型
  • 第五個是擴展模板的變量或包含URI模板變量的映射
@Test
void contextLoads() {//請求地址
    String url = "http://httpbin.org/post";
    User user = new User();
    user.setName("彭于晏");
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    HttpEntityuserHttpEntity = new HttpEntity<>(user, httpHeaders);
    ResponseEntityexchange = restTemplate.exchange(url, HttpMethod.POST, userHttpEntity, Object.class);
    System.out.println(exchange);
}

? 上述代碼模擬了一個簡單的POST請求 可以理解為可以動態(tài)的指定請求方法和請求實體的一個方法。

響應實體

image-20220416154441113


EXECUTE
  • T execute()

? 該方法就是執(zhí)行請求的方法,我們可以發(fā)現(xiàn)上述的所有方法的最后執(zhí)行都是調用的該方法執(zhí)行,所以他在RestTemplate中十分重要

? 該方法有五個參數(shù)

  • 服務地址
  • 請求的方法
  • 準備請求的對象(requestCallback
  • 從響應中提取返回值的對象
  • 擴展模板的變量或包含URI模板變量的映射

execute()

@Override
	@Nullable
	publicT execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
			@Nullable ResponseExtractorresponseExtractor, Object... uriVariables) throws RestClientException {URI expanded = getUriTemplateHandler().expand(url, uriVariables);
		return doExecute(expanded, method, requestCallback, responseExtractor);
	}

? 通過上述源碼我們可以發(fā)現(xiàn)execute()方法只是將我們傳入的String類型的URL轉換為了URL類型,最后執(zhí)行請求是由doExecute()方法


doExecute()

? 這里需要了解兩個類:RequestCallbackResPonseExtractor

?RequestCallback: 用于操作請求頭和body,在請求發(fā)出前執(zhí)行。不需要關心關閉請求或處理錯誤:這都將由RestTemplate處理。

? 該接口有兩個實現(xiàn)類:

?img

?ResPonseExtractor: 解析HTTP響應的數(shù)據(jù),而且不需要擔心異常和資源的關閉。

? 該接口在RestTemplate中同樣有兩個實現(xiàn)類:

HeadersExtractor提取響應HttpHeaders的響應提取器。直接提取響應體中的響應頭
ResponseEntityResponseExtractorHttpEntity的響應提取器。可以獲取響應實體里面包括響應頭,響應體等。具體請查看HttpEntity
@Test
void contextLoads() {//請求地址
    String url = "http://httpbin.org/post";
    User user = new User();
    user.setName("彭于晏");
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    HttpEntityuserHttpEntity = new HttpEntity<>(user, httpHeaders);
    ResponseEntityexecute = restTemplate.execute(url, HttpMethod.POST, restTemplate.httpEntityCallback(userHttpEntity), restTemplate.responseEntityExtractor(Object.class));
    System.out.println(execute);
}

image-20220416161653708


解惑
  • 前面我們介紹方法的時候發(fā)現(xiàn)有個一個可變參數(shù),那個參數(shù)被描述成了擴展模板的變量或是包含URI模板變量的映射

我們來簡單看一下這個參數(shù),我們知道請求傳參可以通過url拼接參數(shù)的方式傳參,拼接參數(shù)也分為兩種:

  • 路徑中嵌入占位的格式(http://httpbin.org/{1}/post)也叫模板映射
  • 末尾添加Key-value格式(http://httpbin.org/post?name="彭于晏")即擴展模板的變量
  • 當我們最后一參數(shù)傳入map時會以key-value的格式拼接在URL后(通俗的說就是這樣設置的變量會跟著URL路徑后面)

?http://httpbin.org/post?name="彭于晏"

@Test
void contextLoads() {//請求地址
    String url = "http://httpbin.org/get";
    HashMapmap = new HashMap<>();
    map.put("name","彭于晏");
    Object forObject = restTemplate.getForObject(url, Object.class, map);
    System.out.println(forObject);
}
  • 當我們傳入簡單的對象如String,Integer時且路徑中有嵌入的占位符時就會代替調用URL中占位符
@Test
void contextLoads() {//請求地址
    String url = "http://httpbin.org/{2}/get";
    HashMapmap = new HashMap<>();
    Object forObject = restTemplate.getForObject(url, Object.class, 99);
    System.out.println(forObject);
}

image-20220416163605771


參考

spring cloud 做微服務時關于RestTemplate中的各種請求方法的使用總結_DWT_CCFK的博客-博客

RestTemplate 詳解 - 知乎 (zhihu.com)

RestTemplate使用教程 - 簡書 (jianshu.com)


-End-

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁名稱:RestTemplate-創(chuàng)新互聯(lián)
轉載來源:http://jinyejixie.com/article22/gegcc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供電子商務自適應網(wǎng)站、定制開發(fā)網(wǎng)站策劃、建站公司、網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

八宿县| 资兴市| 资中县| 黄山市| 文昌市| 桃江县| 卓资县| 张家界市| 金沙县| 日照市| 浑源县| 普兰县| 周宁县| 印江| 鹿邑县| 镇安县| 济阳县| 原平市| 四会市| 大洼县| 安福县| 大姚县| 富平县| 宁河县| 大石桥市| 封开县| 忻城县| 和平县| 雷州市| 平顶山市| 东兰县| 治县。| 大冶市| 南澳县| 沂源县| 静安区| 大余县| 精河县| 桃江县| 鄂托克前旗| 芜湖市|