欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring RestTemplate具體使用詳解

 更新時間:2019年04月17日 10:21:13   作者:KING磊  
這篇文章主要介紹了Spring RestTemplate具體使用詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1、什么是REST?

REST(RepresentationalState Transfer)是Roy Fielding 提出的一個描述互聯(lián)系統(tǒng)架構(gòu)風(fēng)格的名詞。REST定義了一組體系架構(gòu)原則,您可以根據(jù)這些原則設(shè)計以系統(tǒng)資源為中心的Web 服務(wù),包括使用不同語言編寫的客戶端如何通過 HTTP處理和傳輸資源狀態(tài)。

為什么稱為 REST?Web本質(zhì)上由各種各樣的資源組成,資源由URI 唯一標(biāo)識。瀏覽器(或者任何其它類似于瀏覽器的應(yīng)用程序)將展示出該資源的一種表現(xiàn)方式,或者一種表現(xiàn)狀態(tài)。如果用戶在該頁面中定向到指向其它資源的鏈接,則將訪問該資源,并表現(xiàn)出它的狀態(tài)。這意味著客戶端應(yīng)用程序隨著每個資源表現(xiàn)狀態(tài)的不同而發(fā)生狀態(tài)轉(zhuǎn)移,也即所謂REST。

2、REST成熟度的四個層次

第一個層次(Level0)的Web 服務(wù)只是使用 HTTP 作為傳輸方式,實際上只是遠(yuǎn)程方法調(diào)用(RPC)的一種具體形 式。SOAP和 XML-RPC都屬于此類。

第二個層次(Level1)的Web 服務(wù)引入了資源的概念。每個資源有對應(yīng)的標(biāo)識符和表達(dá)。

第三個層次(Level2)的Web 服務(wù)使用不同的 HTTP 方法來進(jìn)行不同的操作,并且使用HTTP 狀態(tài)碼來表示不同的結(jié)果。如 HTTPGET 方法來獲取資源,HTTPDELETE 方法來刪除資源。

第四個層次(Level3)的Web 服務(wù)使用 HATEOAS。在資源的表達(dá)中包含了鏈接信息??蛻舳丝梢愿鶕?jù)鏈接來發(fā)現(xiàn)可以執(zhí)行的動作。

其中第三個層次建立了創(chuàng)建、讀取、更新和刪除(create,read, update, and delete,CRUD)操作與 HTTP方法之間的一對一映射。根據(jù)此映射:

(1)若要在服務(wù)器上創(chuàng)建資源,應(yīng)該使用POST 方法。

(2)若要檢索某個資源,應(yīng)該使用GET 方法。

(3)若要更改資源狀態(tài)或?qū)ζ溥M(jìn)行更新,應(yīng)該使用PUT 方法。

(4)若要刪除某個資源,應(yīng)該使用DELETE 方法。

3、HTTP請求的方法

(1)GET:通過請求URI得到資源
(2)POST:用于添加新的內(nèi)容
(3)PUT:用于修改某個內(nèi)容,若不存在則添加
(4)DELETE:刪除某個內(nèi)容
(5)OPTIONS :詢問可以執(zhí)行哪些方法
(6)HEAD :類似于GET, 但是不返回body信息,用于檢查對象是否存在,以及得到對象的元數(shù)據(jù)
(7)CONNECT :用于代理進(jìn)行傳輸,如使用SSL
(8)TRACE:用于遠(yuǎn)程診斷服務(wù)器

4、HTTP請求的狀態(tài)碼

(1)成功Successful2xx:此類狀態(tài)碼標(biāo)識客戶端的請求被成功接收、理解并接受。常見如200(OK)、204(NoContent)。
(2)重定向Redirection3xx:這個類別的狀態(tài)碼標(biāo)識用戶代理要做出進(jìn)一步的動作來完成請求。常見如301(MovedPermanently)、302(MovedTemprarily)。
(3)客戶端錯誤Client Error 4xx:4xx類別的狀態(tài)碼是當(dāng)客戶端象是出錯的時使用的。常見如400(BadRequest)、401(Unauthorized)、403(Forbidden)、404(NotFound)。
(4)服務(wù)器錯誤Server Error 5xx:響應(yīng)狀態(tài)碼以5開頭表示服務(wù)器知道自己出錯或者沒有能力執(zhí)行請求。常見如500(InternalServer Error)、502(BadGateway)、504(GatewayTimeout)。

5、RestTemplate

5.1 簡介

Spring'scentral class for synchronous client-side HTTP access.It simplifies communication with HTTPservers, and enforces RESTful principles. Ithandles HTTP connections, leaving application code to provide URLs(with possible template variables) andextract results.

簡單說就是:簡化了發(fā)起HTTP請求以及處理響應(yīng)的過程,并且支持REST。為什么說簡化了呢?

來看兩種實現(xiàn)方式

(1)使用java.net包下的URLConnection建立連接

String result= ""; 
  BufferedReaderin = null; 
  try { 
   String urlNameString= url +"?" + param; 
   URL realUrl= new URL(urlNameString); 
   // 打開和URL之間的連接 
   URLConnectionconnection = realUrlopenConnection(); 
   // 設(shè)置通用的請求屬性 
   connectionsetRequestProperty("accept","*/*"); 
   connectionsetRequestProperty("connection","Keep-Alive"); 
   connectionsetRequestProperty("user-agent", 
     "Mozilla/0(compatible; MSIE 0; Windows NT 1;SV1)"); 
   // 建立實際的連接 
   connectionconnect(); 
   // 獲取所有響應(yīng)頭字段 
   Map<String,List<String>> map = connectiongetHeaderFields(); 
   // 遍歷所有的響應(yīng)頭字段 
   for(String key : mapkeySet()) { 
    Systemoutprintln(key+ "--->" + mapget(key)); 
   } 
   // 定義 BufferedReader輸入流來讀取URL的響應(yīng) 
   in =new BufferedReader(newInputStreamReader( 
     connectiongetInputStream())); 
   String line; 
   while ((line = inreadLine())!= null) { 
    result += line; 
   } 
  } catch (Exception e) { 
   … 
  } 
  // 使用finally塊來關(guān)閉輸入流 
  finally{ 
   // 關(guān)閉流 
  } 

(2)使用RestTempalte

ResponseEntity<SsoUrlPrm>result = restTemplate.getForEntity(requestPathUrl,SsoUrlPrm.class); 

5.2 對外開放的接口

(1)

DELETE delete
GET getForObject
  getForEntity
HEAD headForHeaders
OPTIONS optionsForAllow
POST postForLocation
  postForObject
PUT put
any exchange
  execute

(2)每一個小類又分三種,這三種有什么區(qū)別?* 第一種和第二種的首個參數(shù)都是用String表示一個URI。但它們的最后一個參數(shù)分別是Object[]和Map* 第三種的首個參數(shù)使用java.net.URI表示一個URI。且只有兩個參數(shù)

這是因為,String類型的URI支持占位符。比如:

restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}",String.class,"42", "21");

那么最終訪問的URI為:http://example.com/hotels/42/bookings/21

但是String有一個小缺陷:String形式的URI會被URL編碼兩次(URL encode請自行百度),這就要求服務(wù)器在獲取URI中的參數(shù)時主動進(jìn)行一次解碼,但如果服務(wù)的提供者不這么做呢?

這時就需要使用不會使用任何編碼的java.net.URI

PS:參數(shù)‘Class<T>responseType'定義了返回數(shù)據(jù)的類型。

(3)Exchange與其它接口的不同:

>允許調(diào)用者指定HTTP請求的方法(GET,POST,PUT等)

>可以在請求中增加body以及頭信息,其內(nèi)容通過參數(shù)‘HttpEntity<?>requestEntity'描述

>exchange支持‘含參數(shù)的類型'(即泛型類)作為返回類型,該特性通過‘ParameterizedTypeReference<T>responseType'描述。比如:

List<String> a = new ArrayList<String>(); 
System.out.println(a.getClass()); 
System.out.println(a.getClass().getGenericSuperclass()); 
ParameterizedTypeReference pt = new ParameterizedTypeReference<ArrayList<String>>() {}; 
System.out.println(pt.getType()); 

得到的結(jié)果是:

class java.util.ArrayList 
java.util.AbstractList<E> 
java.util.ArrayList<java.lang.String> 

* 這是因為ParameterizedTypeReference<ArrayList<String>>并不根據(jù)實參而是使用getGenericSuperclass()方法獲取其父類的類型(注意這里的new有花括號,是ParameterizedTypeReference的子類),父類的類型通過java.lang.reflect.Type描述,然后通過Type的getActualTypeArguments()獲得了父類的實參類型,注意得到的Type類,并不是class類。

(4)excute

所有的get、post、delete、put、options、head、exchange方法最終調(diào)用的都是excute方法。舉個栗子:

@Override 
public <T> T getForObject(String url, Class<T> responseType, Object urlVariables) throws RestClientException { 
 RequestCallback requestCallback =  acceptHeaderRequestCallback(responseType); 
 HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger); 
 return execute(url, HttpMethodGET, requestCallback, responseExtractor, urlVariables); 
} 

Excute方法只是將String格式的URI轉(zhuǎn)成了java.net.URI,之后調(diào)用了doExecute方法。整個調(diào)用過程


6.doExcute

6.1 定義

protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,ResponseExtractor<T> responseExtractor) throws RestClientException {…} 

這里需要了解兩個類: RequestCallback &ResponseExtractor

6.2RequestCallback

Callback interface for code that operates on a ClientHttpRequest. Allows to manipulate the request headers, and write to the request body.

簡單說:用于操作請求頭和body,在請求發(fā)出前執(zhí)行。

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

AcceptHeaderRequestCallback 只處理請求頭,用于getXXX()方法。
HttpEntityRequestCallback 繼承于AcceptHeaderRequestCallback可以處理請求頭和body,用于putXXX()、postXXX()和exchange()方法。

* DELETE、HEAD、OPTIONS沒有使用這個接口。

6.3 發(fā)起請求

6.4ResponseExtractor

6.4.1 定義

Generic callback interface used by RestTemplate's retrieval methods Implementations of this interface perform the actual work of extracting data from a ClientHttpResponse, but don't need to worry about exception handling or closing resources.

簡單說:解析HTTP響應(yīng)的數(shù)據(jù),而且不需要擔(dān)心異常和資源的關(guān)閉。

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

HeadersExtractor 用于提取請求頭。
HttpMessageConverterExtractor 用于提取響應(yīng)body。
ResponseEntityResponseExtractor 使用HttpMessageConverterExtractor提取body(委托模式),然后將body和響應(yīng)頭、狀態(tài)封裝成ResponseEntity對象。

6.4.2 提取響應(yīng)body

提取分三步:

(1)提取器HttpMessageConverterExtractor尋找可用的轉(zhuǎn)化器在默認(rèn)的RestTemplate的構(gòu)造函數(shù)中初始化了轉(zhuǎn)化器集合,包括:

轉(zhuǎn)化器

可轉(zhuǎn)化的類型
ByteArrayHttpMessageConverter byte[]
StringHttpMessageConverter String
ResourceHttpMessageConverter Resource
SourceHttpMessageConverter javax.xml.transform.*
AllEncompassingFormHttpMessageConverter MultiValueMap
Jaxb2RootElementHttpMessageConverter XmlRootElement,XmlType(注解)
...  
MappingJackson2HttpMessageConverter Json

除了前五個,其他的轉(zhuǎn)化器會由classloader嘗試加載某個類來判斷工程是否包含某個包,而后決定是否加入轉(zhuǎn)化器集合。

提取器遍歷轉(zhuǎn)化器集合以查找可用的轉(zhuǎn)化器,其中MappingJackson2HttpMessageConverter總是在最后一個,因為該類實現(xiàn)了GenericHttpMessageConverter,算是一個通用轉(zhuǎn)化器,只有在找不到合適的轉(zhuǎn)化器時才輪到它。Spring提供了一個該類的實現(xiàn),以保證總是能得到該類。

(2)轉(zhuǎn)化器尋找可用的反序列化器

轉(zhuǎn)化器持有一個反序列化器緩存集合,首先從緩存中尋找

如果已有可用的反序列化器,則直接返回。否則創(chuàng)建一個新的反序列化器。

反序列化器保存著待反序列化類的域、方法、構(gòu)造器等信息,反序列化時就是使用構(gòu)造器創(chuàng)建了一個新的實例。

以jackson為例,創(chuàng)建反序列化器的過程在jackson-databind-xxx.jar中,有興趣的可以看一下。調(diào)用棧如下(由下往上找):

BeanDeserializerFactory.addBeanProps/addObjectIdReader/addReferenceProperties/addInjectables
BeanDeserializerFactory.buildBeanDeserializer
BeanDeserializerFactory.createBeanDeserializer

(3)反序列化器執(zhí)行反序列化

TOKEN

Json的一個或一組字符
START_OBJECT {
END_OBJECT }
START_ARRAY [
END_ARRAY ]
VALUE_TRUE true
VALUE_FALSE false
...  

調(diào)用棧:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解springboot解決第三方依賴jar包的問題

    詳解springboot解決第三方依賴jar包的問題

    本篇文章主要介紹了詳解springboot解決第三方依賴jar包的問題,解決了第三方依賴jar包的問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • Maven的配置文件pom.xml詳解(含常用plugin)

    Maven的配置文件pom.xml詳解(含常用plugin)

    pom.xml是Maven項目的核心配置文件,它是 項目對象模型 - Project Object Model(POM)的縮寫,本文我們將全面解析pom.xml,了解其結(jié)構(gòu)和屬性,以及如何使用它來管理項目,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由

    springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由

    這篇文章主要介紹了springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java數(shù)據(jù)類型超詳細(xì)示例講解

    Java數(shù)據(jù)類型超詳細(xì)示例講解

    Java程序中要求參與的計算的數(shù)據(jù),必須要保證數(shù)據(jù)類型的一致性,如果數(shù)據(jù)類型不一致將發(fā)生類型的轉(zhuǎn)換。本文將通過示例詳細(xì)說說Java中數(shù)據(jù)類型的轉(zhuǎn)換,感興趣的可以了解一下
    2022-11-11
  • SpringBoot測試時卡在Resolving Maven dependencies的問題

    SpringBoot測試時卡在Resolving Maven dependencies的問題

    這篇文章主要介紹了SpringBoot測試時卡在Resolving Maven dependencies的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • maven國內(nèi)鏡像配置的方法步驟

    maven國內(nèi)鏡像配置的方法步驟

    這篇文章主要介紹了maven國內(nèi)鏡像配置的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之時間復(fù)雜度與空間復(fù)雜度

    Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之時間復(fù)雜度與空間復(fù)雜度

    對于一個算法,其時間復(fù)雜度和空間復(fù)雜度往往是相互影響的,當(dāng)追求一個較好的時間復(fù)雜度時,可能會使空間復(fù)雜度的性能變差,即可能導(dǎo)致占用較多的存儲空間,這篇文章主要給大家介紹了關(guān)于Java時間復(fù)雜度、空間復(fù)雜度的相關(guān)資料,需要的朋友可以參考下
    2022-02-02
  • java多線程從入門到精通看這篇就夠了

    java多線程從入門到精通看這篇就夠了

    熟悉 Java 多線程編程的同學(xué)都知道,當(dāng)我們線程創(chuàng)建過多時,容易引發(fā)內(nèi)存溢出,因此我們就有必要使用線程池的技術(shù)了,今天通過本文給大家分享java多線程從入門到精通的相關(guān)知識,一起看看吧
    2021-06-06
  • spring boot+redis 監(jiān)聽過期Key的操作方法

    spring boot+redis 監(jiān)聽過期Key的操作方法

    這篇文章主要介紹了spring boot+redis 監(jiān)聽過期Key,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Springboot中實現(xiàn)接口冪等性的4種方案小結(jié)

    Springboot中實現(xiàn)接口冪等性的4種方案小結(jié)

    本文主要介紹了Springboot中實現(xiàn)接口冪等性,包含數(shù)據(jù)庫的冪等,數(shù)據(jù)庫的冪等,Redis的冪等性和Token + 時間戳的冪等性,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03

最新評論