Spring RestTemplate詳解
1、什麼是REST?
REST(RepresentationalState Transfer)是Roy Fielding 提出的一個描述互聯絡統架構風格的名詞。REST定義了一組體系架構原則,您可以根據這些原則設計以系統資源為中心的Web 服務,包括使用不同語言編寫的客戶端如何通過 HTTP處理和傳輸資源狀態。
為什麼稱為 REST?Web本質上由各種各樣的資源組成,資源由URI 唯一標識。瀏覽器(或者任何其它類似於瀏覽器的應用程式)將展示出該資源的一種表現方式,或者一種表現狀態。如果使用者在該頁面中定向到指向其它資源的連結,則將訪問該資源,並表現出它的狀態。這意味著客戶端應用程式隨著每個資源表現狀態的不同而發生狀態轉移,也即所謂REST。
2、REST成熟度的四個層次
第一個層次(Level0)的Web 服務只是使用 HTTP 作為傳輸方式,實際上只是遠端方法呼叫(RPC)的一種具體形 式。SOAP和 XML-RPC都屬於此類。
第二個層次(Level1)的Web 服務引入了資源的概念。每個資源有對應的識別符號和表達。
第三個層次(Level2)的Web 服務使用不同的 HTTP 方法來進行不同的操作,並且使用HTTP 狀態碼來表示不同的結果。如 HTTPGET 方法來獲取資源,HTTPDELETE 方法來刪除資源。
第四個層次(Level3)的Web 服務使用 HATEOAS。在資源的表達中包含了連結資訊。客戶端可以根據連結來發現可以執行的動作。
其中第三個層次建立了建立、讀取、更新和刪除(create,read, update, and delete,CRUD)操作與 HTTP方法之間的一對一對映。根據此對映:
(1)若要在伺服器上建立資源,應該使用POST 方法。
(2)若要檢索某個資源,應該使用GET 方法。
(3)若要更改資源狀態或對其進行更新,應該使用PUT 方法。
(4)若要刪除某個資源,應該使用DELETE 方法。
3、HTTP請求的方法
(1)GET:通過請求URI得到資源
(2)POST:用於新增新的內容
(3)PUT:用於修改某個內容,若不存在則新增
(4)DELETE:刪除某個內容
(5)OPTIONS :詢問可以執行哪些方法
(6)HEAD :類似於GET, 但是不返回body資訊,用於檢查物件是否存在,以及得到物件的元資料
(7)CONNECT :用於代理進行傳輸,如使用SSL
(8)TRACE:用於遠端診斷伺服器
4、HTTP請求的狀態碼
(1)成功Successful2xx:此類狀態碼標識客戶端的請求被成功接收、理解並接受。常見如200(OK)、204(NoContent)。
(2)重定向Redirection3xx:這個類別的狀態碼標識使用者代理要做出進一步的動作來完成請求。常見如301(MovedPermanently)、302(MovedTemprarily)。
(3)客戶端錯誤Client Error 4xx:4xx類別的狀態碼是當客戶端象是出錯的時使用的。常見如400(BadRequest)、401(Unauthorized)、403(Forbidden)、404(NotFound)。
(4)伺服器錯誤Server Error 5xx:響應狀態碼以5開頭表示伺服器知道自己出錯或者沒有能力執行請求。常見如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.
簡單說就是:簡化了發起HTTP請求以及處理響應的過程,並且支援REST。為什麼說簡化了呢?
來看兩種實現方式
(1)使用java.net包下的URLConnection建立連線
- String result= "";
- BufferedReaderin = null;
- try {
- String urlNameString= url +"?" + param;
- URL realUrl= new URL(urlNameString);
- // 開啟和URL之間的連線
- URLConnectionconnection = realUrl.openConnection();
- // 設定通用的請求屬性
- connection.setRequestProperty("accept","*/*");
- connection.setRequestProperty("connection","Keep-Alive");
- connection.setRequestProperty("user-agent",
- "Mozilla/4.0(compatible; MSIE 6.0; Windows NT 5.1;SV1)");
- // 建立實際的連線
- connection.connect();
- // 獲取所有響應頭欄位
- Map<String,List<String>> map = connection.getHeaderFields();
- // 遍歷所有的響應頭欄位
- for(String key : map.keySet()) {
- System.out.println(key+ "--->" + map.get(key));
- }
- // 定義 BufferedReader輸入流來讀取URL的響應
- in =new BufferedReader(newInputStreamReader(
- connection.getInputStream()));
- String line;
- while ((line = in.readLine())!= null) {
- result += line;
- }
- } catch (Exception e) {
- …
- }
- // 使用finally塊來關閉輸入流
- finally{
- // 關閉流
- }
(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)每一個小類又分三種,這三種有什麼區別?
* 第一種和第二種的首個引數都是用String表示一個URI。但它們的最後一個引數分別是Object[]和Map * 第三種的首個引數使用java.net.URI表示一個URI。且只有兩個引數這是因為,String型別的URI支援佔位符。比如:
restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}",String.class,"42", "21");
但是String有一個小缺陷:String形式的URI會被URL編碼兩次(URL encode請自行百度),這就要求伺服器在獲取URI中的引數時主動進行一次解碼,但如果服務的提供者不這麼做呢?
這時就需要使用不會使用任何編碼的java.net.URI
PS:引數‘Class<T> responseType’定義了返回資料的型別。
(3)Exchange
與其它介面的不同:>允許呼叫者指定HTTP請求的方法(GET,POST,PUT等)
>可以在請求中增加body以及頭資訊,其內容通過引數‘HttpEntity<?>requestEntity’描述
>exchange支援‘含引數的型別’(即泛型類)作為返回型別,該特性通過‘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());
得到的結果是:
- class java.util.ArrayList
- java.util.AbstractList<E>
- java.util.ArrayList<java.lang.String>
* 這是因為ParameterizedTypeReference<ArrayList<String>>並不根據實參而是使用getGenericSuperclass()方法獲取其父類的型別(注意這裡的new有花括號,是ParameterizedTypeReference的子類),父類的型別通過java.lang.reflect.Type描述,然後通過Type的getActualTypeArguments()獲得了父類的實參型別,注意得到的Type類,並不是class類。
(4)excute
所有的get、post、delete、put、options、head、exchange方法最終呼叫的都是excute方法。舉個栗子:- @Override
- public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws RestClientException {
- RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
- HttpMessageConverterExtractor<T> responseExtractor =
- <span style="white-space:pre"> </span>new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
- return execute(url, HttpMethod.GET, requestCallback, responseExtractor, urlVariables);
- }
Excute方法只是將String格式的URI轉成了java.net.URI,之後呼叫了doExecute方法。整個呼叫過程
6.doExcute
6.1 定義- protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,ResponseExtractor<T> responseExtractor) throws RestClientException {…}
Callback interface for code that operates on a ClientHttpRequest. Allows to manipulate the request headers, and write to the request body.
簡單說:用於操作請求頭和body,在請求發出前執行。
該介面有兩個實現類:
AcceptHeaderRequestCallback | 只處理請求頭,用於getXXX()方法。 |
HttpEntityRequestCallback | 繼承於AcceptHeaderRequestCallback可以處理請求頭和body,用於putXXX()、postXXX()和exchange()方法。 |
* DELETE、HEAD、OPTIONS沒有使用這個介面。 6.3 發起請求 6.4 ResponseExtractor 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響應的資料,而且不需要擔心異常和資源的關閉。 該介面有三個實現類:
HeadersExtractor | 用於提取請求頭。 |
HttpMessageConverterExtractor | 用於提取響應body。 |
ResponseEntityResponseExtractor | 使用HttpMessageConverterExtractor提取body(委託模式),然後將body和響應頭、狀態封裝成ResponseEntity物件。 |
(1)提取器HttpMessageConverterExtractor尋找可用的轉化器 在預設的RestTemplate的建構函式中初始化了轉化器集合,包括:
轉化器 |
可轉化的型別 |
ByteArrayHttpMessageConverter | byte[] |
StringHttpMessageConverter | String |
ResourceHttpMessageConverter | Resource |
SourceHttpMessageConverter | javax.xml.transform.* |
AllEncompassingFormHttpMessageConverter | MultiValueMap |
Jaxb2RootElementHttpMessageConverter | XmlRootElement,XmlType(註解) |
... | |
MappingJackson2HttpMessageConverter | Json |
提取器遍歷轉化器集合以查詢可用的轉化器,其中MappingJackson2HttpMessageConverter總是在最後一個,因為該類實現了GenericHttpMessageConverter,算是一個通用轉化器,只有在找不到合適的轉化器時才輪到它。Spring提供了一個該類的實現,以保證總是能得到該類。
(2)轉化器尋找可用的反序列化器 轉化器持有一個反序列化器快取集合,首先從快取中尋找
如果已有可用的反序列化器,則直接返回。否則建立一個新的反序列化器。 反序列化器儲存著待反序列化類的域、方法、構造器等資訊,反序列化時就是使用構造器建立了一個新的例項。 以jackson為例,建立反序列化器的過程在jackson-databind-xxx.jar中,有興趣的可以看一下。呼叫棧如下(由下往上找): BeanDeserializerFactory.addBeanProps/addObjectIdReader/addReferenceProperties/addInjectables
BeanDeserializerFactory.buildBeanDeserializer
BeanDeserializerFactory.createBeanDeserializer
(3)反序列化器執行反序列化
TOKEN |
Json的一個或一組字元 |
START_OBJECT | { |
END_OBJECT | } |
START_ARRAY | [ |
END_ARRAY | ] |
VALUE_TRUE | true |
VALUE_FALSE | false |
... |
呼叫棧:
相關推薦
Spring RestTemplate詳解
1、什麼是REST? REST(RepresentationalState Transfer)是Roy Fielding 提出的一個描述互聯絡統架構風格的名詞。REST定義了一組體系架構原則,您可以根據這些原則設計以系統資源為中心的Web 服務,包括使用不同語言編寫的客戶端如何通過 HTTP處理和
筆記:Spring Cloud Ribbon RestTemplate 詳解
定義 方法 template 包含 mediatype pst ron request temp 詳細介紹RestTemplate 針對幾種不同請求類型和參數類型的服務調用實現,示例代碼中的 restTemplate 都是通過Spring 註
Spring Mvc詳解
spring mvc一、spring mvc處理請求的流程。客戶端發出http請求,如果匹配到DispatcherServlet的請求映射路徑,則web容器將請求轉交給DispatcherServlet處理。DispatcherServlet接受到請求後,根據請求的信息和HandlerMapping的配置,找
Spring JdbcTemplate詳解
bject 方便 object 不能 數據源 cte led 執行 pre JdbcTemplate簡介 Spring對數據庫的操作在jdbc上面做了深層次的封裝,使用spring的註入功能,可以把DataSource註冊到JdbcTemplate之中。 Jdb
Spring AOP詳解
開發 blank 關註 proxy 系統 frame main函數 lns 功能 一.前言 在以前的項目中,很少去關註spring aop的具體實現與理論,只是簡單了解了一下什麽是aop具體怎麽用,看到了一篇博文寫得還不錯,就轉載來學習一下,博文地址:htt
【轉載】Spring AOP詳解 、 JDK動態代理、CGLib動態代理
rto 工廠 第一個 lec 僅支持 sel clas sleep gpo 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspect Oriented Programing的簡稱,面向切面
01-spring配置詳解
eth height 直接 arr work ssp creat exp context 1 bean元素 <!--將User對象交給spring容器進行管理 --> <!-- Bean元素:使用該元素描述需要spring容器管理的對象
Spring Aop 詳解
RR 透明 IT obj owin target 面向切面編程 阻止 責任 一、AOP 簡介 AOP(Aspect Oriented Programming),即面向切面編程,可以說是OOP(Object Oriented Programming,面向對象編程)的補充和完
Spring JdbcTemplate詳解(9)
turn 插入 values sca bat his ron system ati JdbcTemplate簡介 Spring對數據庫的操作在jdbc上面做了深層次的封裝,使用spring的註入功能,可以把DataSource註冊到JdbcTemplate之中。 J
spring事務詳解
table 失敗 異常 ted res source 行操作 事務傳播 操作 1.spring事務原理:spring事務的本質其實就是數據庫對事務的支持,沒有數據庫對事務的支持就無法提供事務的功能。 2.spring事務傳播屬性: PROPAGATION_REQUIRED
spring-data詳解之spring-data-jpa:簡單三步快速上手spring-data-jpa開發
事務管理 out don 前言 map lns xid public lease 前言: 基於spring framework 4.x或spring boot 1.x開發環境 務必註意以下版本問題:Spring framework4.x(Spring boot1.x)對應s
Dubbo啟動過程(Spring方式)詳解
一、使用Spring xml配置方式的啟動過程 1. 解析XML,註冊Bean 2. 監聽Spring事件 3. 啟動或關閉dubbo 二、詳細過程 1. 解析XML,註冊Bean 利用Spring提供的NamespaceHandler擴充套件機制,META-INF下放兩個spri
轉:Spring AOP詳解
一.前言 博文地址:http://www.cnblogs.com/xrq730/p/4919025.html AOP AOP(Aspect Oriented Programming),即面向切面程式設計,可以說是OOP(Object Oriented Programming,面向物件
spring mvc Spring區別詳解
spring boot只是一個配置工具,整合工具,輔助工具. springmvc是框架,專案中實際執行的程式碼 Spring 框架就像一個家族,有眾多衍生產品例如 boot、security、jpa等等。但他們的基礎都是Spring 的ioc和 ao
如何優雅的使用Springboot (RestTemplate詳解)
RestTemplate是Spring提供的用於訪問Rest服務的客戶端,RestTemplate提供了多種便捷訪問遠端Http服務的方法,能夠大大提高客戶端的編寫效率。 我之前的HTTP開發是用apache的HttpClient開發,程式碼複雜,還得操心資源回收等。程式碼
07.Spring-配置詳解-Spirng建立物件的三種方式
測試類 package vc.helloworld.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springfra
06.Spring-配置詳解-bean元素
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/ca
spring事務詳解(二)原始碼詳解
系列目錄 spring事務詳解(三)使用樣例 spring事務詳解(四)測試驗證 spring事務詳解(五)總結提高 一、引子 在Spring中,事務有兩種實現方式: 程式設計式事務管理: 程式設計式事務管理使用TransactionTemplate可實現更細粒度的事務控制。 申明
spring事務詳解(二)簡單樣例
系列目錄 spring事務詳解(四)測試驗證 spring事務詳解(五)總結提高 一、引子 在Spring中,事務有兩種實現方式: 程式設計式事務管理: 程式設計式事務管理使用底層原始碼可實現更細粒度的事務控制。spring推薦使用TransactionTemplate,典型的模板模
【Diary】【2018-10-20】【RestTemplate詳解】
1.Get請求 第一種:getForEntity getForEntity函式,該方法返回的是ResponseEntity,該物件是SpringHttp請求響應的封裝,其中封裝了Http的幾個重要元素,比如Http請求狀態碼的列舉物件HttpStatus,還有Http的請