本文提供了RESTFul API的基礎知識,包括RESTFul API的基本概念,HTTP協議相關知識,Spring對REST的支持等。javascript
以信息爲中心的表述性狀態轉移(Representational State Transfer,REST)已成爲替換傳統SOAP Web服務的流行方案。他們的主要區別是,SOAP通常會關注行爲和處理,而REST關注的是要處理的數據。html
REST不是「基於URL的Web服務」,也不是另外一種類型的遠程過程調用(remote procedure call,RPC)機制。RPC是面向服務的,並關注於行爲和動做;而REST是面向資源的,強調描述應用程序的事物和名詞。java
RE-表述性(Representational):REST資源實際上能夠用各類形式來進行表述,包括XML、JSON(JavaScript Object Notation)甚至HTML——最適合資源使用者的任意形式。git
S-狀態(State):當使用REST的時候,咱們更關注資源的狀態而不是對資源採起的行爲。github
T-轉移(Transfer):REST涉及到轉移資源數據,它以某種表述性形式從一個應用轉移到另外一個應用。web
簡單來講,REST就是將資源的狀態以最適合客戶端或服務端的形式從服務器端轉移到客戶端(或者反過來)spring
在REST中,資源經過URL進行識別和定位。至於RESTful URL的結構並無嚴格的規則,可是URL應該可以識別資源,而不是簡單的發一條命令到服務器上。再次強調,關注的核心是事物,而不是行爲。json
REST中的資源所指的不是數據,而是數據和表現形式的組合,好比「最新訪問的10位會員」和「最活躍的10位會員」在數據上可能有重疊或者徹底相同,而因爲他們的表現形式不一樣,因此被歸爲不一樣的資源。瀏覽器
REST中會有行爲,它們是經過HTTP方法來定義的。具體來說,也就是GET、POST、PUT、DELETE、PATCH以及其餘的HTTP方法構成了REST中的動做。緩存
這些HTTP方法一般會匹配爲以下的CRUD動做:
儘管一般來說,HTTP方法會映射爲CRUD動做,但這並非嚴格的限制。有時候,PUT能夠用來建立新資源,POST能夠用來更新資源。實際上,POST請求非冪等性(non-idempotent)的特色使其成爲一個很是靈活的方法,對於沒法適應其餘HTTP方法語義的操做,它都可以勝任。
HTTP頭信息提供了關於請求,響應或者其餘的發送實體的信息。
HTTP的頭信息包括通用頭、請求頭、響應頭和實體頭四個部分。每一個頭域由一個域名,冒號(:)和域值三部分組成。
請求頭:
Header | 解釋 | 示例 |
---|---|---|
Accept | 指定客戶端可以接收的內容類型 | Accept: text/plain, text/html |
Accept-Charset | 瀏覽器能夠接受的字符編碼集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定瀏覽器能夠支持的web服務器返回內容壓縮編碼類型。 | Accept-Encoding: compress, gzip |
Accept-Language | 瀏覽器可接受的語言 | Accept-Language: en,zh |
Accept-Ranges | 能夠請求網頁實體的一個或者多個子範圍字段 | Accept-Ranges: bytes |
Authorization | HTTP受權的受權證書 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定請求和響應遵循的緩存機制 | Cache-Control: no-cache |
Connection | 表示是否須要持久鏈接。(HTTP 1.1默認進行持久鏈接) | Connection: close |
Cookie | HTTP請求發送時,會把保存在該請求域名下的全部cookie值一塊兒發送給web服務器 | 。 Cookie: $Version=1; Skin=new; |
Content-Length | 請求的內容長度 | Content-Length: 348 |
Content-Type | 請求的與實體對應的MIME信息 | Content-Type: application/x-www-form-urlencoded |
Date | 請求發送的日期和時間 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 請求的特定的服務器行爲 | Expect: 100-continue |
From | 發出請求的用戶的Email | From: user@email.com |
Host | 指定請求的服務器的域名和端口號 | Host: www.zcmhi.com |
If-Match | 只有請求內容與實體相匹配纔有效 | If-Match: 「737060cd8c284d8af7ad3082f209582d」 |
If-Modified-Since | 若是請求的部分在指定時間以後被修改則請求成功,未被修改則返回304代碼 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 若是內容未改變返回304代碼,參數爲服務器先前發送的Etag,與服務器迴應的Etag比較判斷是否改變 | If-None-Match: 「737060cd8c284d8af7ad3082f209582d」 |
If-Range | 若是實體未改變,服務器發送客戶端丟失的部分,不然發送整個實體。參數也爲Etag | If-Range: 「737060cd8c284d8af7ad3082f209582d」 |
If-Unmodified-Since | 只在實體在指定時間以後未被修改才請求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制信息經過代理和網關傳送的時間 | Max-Forwards: 10 |
Pragma | 用來包含實現特定的指令 | Pragma: no-cache |
Proxy-Authorization | 鏈接到代理的受權證書 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 只請求實體的一部分,指定範圍 | Range: bytes=500-999 |
Referer | 先前網頁的地址,當前請求網頁緊隨其後,即來路 | Referer: www.zcmhi.com/archives/71… |
TE | 客戶端願意接受的傳輸編碼,並通知服務器接受接受尾加頭信息 | TE: trailers,deflate;q=0.5 |
Upgrade | 向服務器指定某種傳輸協議以便服務器進行轉換(若是支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agen | t User-Agent的內容包含發出請求的用戶信息 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 通知中間網關或代理服務器地址,通訊協議 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 關於消息實體的警告信息 | Warn: 199 Miscellaneous warning |
響應頭:
Header | 解釋 | 示例 |
---|---|---|
Accept-Ranges | 代表服務器是否支持指定範圍請求及哪一種類型的分段請求 | Accept-Ranges: bytes |
Age | 從原始服務器到代理緩存造成的估算時間(以秒計,非負 | ) Age: 12 |
Allow | 對某網絡資源的有效的請求行爲,不容許則返回405 | Allow: GET, HEAD |
Cache-Control | 告訴全部的緩存機制是否能夠緩存及哪一種類型 | Cache-Control: no-cache |
Content-Encoding | web服務器支持的返回內容壓縮編碼類型。 | Content-Encoding: gzip |
Content-Language | 響應體的語言 | Content-Language: en,zh |
Content-Length | 響應體的長度 | Content-Length: 348 |
Content-Location | 請求資源可替代的備用的另外一地址 | Content-Location: /index.htm |
Content-MD5 | 返回資源的MD5校驗值 | Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== |
Content-Range | 在整個返回體中本部分的字節位置 | Content-Range: bytes 21010-47021/47022 |
Content-Type | 返回內容的MIME類型 | Content-Type: text/html; charset=utf-8 |
Date | 原始服務器消息發出的時間 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
ETag | 請求變量的實體標籤的當前值 | ETag: 「737060cd8c284d8af7ad3082f209582d」 |
Expires | 響應過時的日期和時間 | Expires: Thu, 01 Dec 2010 16:00:00 GMT |
Last-Modified | 請求資源的最後修改時間 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT |
Location | 用來重定向接收方到非請求URL的位置來完成請求或標識新的資源 | Location: www.zcmhi.com/archives/94… |
Pragma | 包括實現特定的指令,它可應用到響應鏈上的任何接收方 | Pragma: no-cache |
Proxy-Authenticate | 它指出認證方案和可應用到代理的該URL上的參數 | Proxy-Authenticate: Basic |
refresh | 應用於重定向或一個新的資源被創造,在5秒以後重定向(由網景提出,被大部分瀏覽器支持) | Refresh: 5; url= www.zcmhi.com/archives/94… |
Retry-After | 若是實體暫時不可取,通知客戶端在指定時間以後再次嘗試 | Retry-After: 120 |
Server | web服務器軟件名稱 | Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) |
Set-Cookie | 設置Http Cookie | Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 |
Trailer | 指出頭域在分塊傳輸編碼的尾部存在 | Trailer: Max-Forwards |
Transfer-Encoding | 文件傳輸編碼 | Transfer-Encoding:chunked |
Vary | 告訴下游代理是使用緩存響應仍是從原始服務器請求 | Vary: * |
Via | 告知代理客戶端響應是經過哪裏發送的 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 警告實體可能存在的問題 | Warning: 199 Miscellaneous warning |
WWW-Authenticate | 代表客戶端請求實體應該使用的受權方案 | WWW-Authenticate: Basic |
HTTP Request Method共計15種:
序號 | 方法 | 描述 |
---|---|---|
1 | GET | 請求指定的頁面信息,並返回實體主體。 |
2 | HEAD | 相似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭 |
3 | POST | 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。 |
4 | PUT | 從客戶端向服務器傳送的數據取代指定的文檔的內容。 |
5 | DELETE | 請求服務器刪除指定的頁面。 |
6 | CONNECT | HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器。 |
7 | OPTIONS | 容許客戶端查看服務器的性能。 |
8 | TRACE | 回顯服務器收到的請求,主要用於測試或診斷。 |
9 | PATCH | 實體中包含一個表,表中說明與該URI所表示的原內容的區別。 |
10 | MOVE | 請求服務器將指定的頁面移至另外一個網絡地址。 |
11 | COPY | 請求服務器將指定的頁面拷貝至另外一個網絡地址。 |
12 | LINK | 請求服務器創建連接關係。 |
13 | UNLINK | 斷開連接關係。 |
14 | WRAPPED | 容許客戶端發送通過封裝的請求。 |
15 | Extension-mothed | 在不改動協議的前提下,可增長另外的方法。 |
其中咱們經常使用的POST請求數據被包含在請求體中,POST請求可能會致使新的資源的創建 和/或 已有資源的修改。
HTTP狀態碼(英語:HTTP Status Code)是用以表示網頁服務器超文本傳輸協議響應狀態的3位數字代碼。
HTTP狀態碼的第一個數字表明瞭響應的五種狀態之一:
Value | Description |
---|---|
1xx: | Informational - Request received, continuing process |
2xx: | Success - The action was successfully received, understood, and accepted |
3xx: | Redirection - Further action must be taken in order to complete the request |
4xx: | Client Error - The request contains bad syntax or cannot be fulfilled |
5xx: | Server Error - The server failed to fulfill an apparently valid request |
根據RFC7231規範,目前有如下HTTP狀態碼:
Value | Description |
---|---|
100 | Continue |
101 | Switching Protocols |
102 | Processing |
103 | Early Hints |
104-199 | Unassigned |
200 | OK |
201 | Created |
202 | Accepted |
203 | Non-Authoritative Information |
204 | No Content |
205 | Reset Content |
206 | Partial Content |
207 | Multi-Status |
208 | Already Reported |
209-225 | Unassigned |
226 | IM Used |
227-299 | Unassigned |
300 | Multiple Choices |
301 | Moved Permanently |
302 | Found |
303 | See Other |
304 | Not Modified |
305 | Use Proxy |
306 | (Unused) |
307 | Temporary Redirect |
308 | Permanent Redirect |
309-399 | Unassigned |
400 | Bad Request |
401 | Unauthorized |
402 | Payment Required |
403 | Forbidden |
404 | Not Found |
405 | Method Not Allowed |
406 | Not Acceptable |
407 | Proxy Authentication Required |
408 | Request Timeout |
409 | Conflict |
410 | Gone |
411 | Length Required |
412 | Precondition Failed |
413 | Payload Too Large |
414 | URI Too Long |
415 | Unsupported Media Type |
416 | Range Not Satisfiable |
417 | Expectation Failed |
418-420 | Unassigned |
421 | Misdirected Request |
422 | Unprocessable Entity |
423 | Locked |
424 | Failed Dependency |
425 | Too Early |
426 | Upgrade Required |
427 | Unassigned |
428 | Precondition Required |
429 | Too Many Requests |
430 | Unassigned |
431 | Request Header Fields Too Large |
432-450 | Unassigned |
451 | Unavailable For Legal Reasons |
452-499 | Unassigned |
500 | Internal Server Error |
501 | Not Implemented |
502 | Bad Gateway |
503 | Service Unavailable |
504 | Gateway Timeout |
505 | HTTP Version Not Supported |
506 | Variant Also Negotiates |
507 | Insufficient Storage |
508 | Loop Detected |
509 | Unassigned |
510 | Not Extended |
511 | Network Authentication Required |
512-599 | Unassigned |
Content-Type,內容類型,通常是指網頁中存在的Content-Type,用於定義網絡文件的類型和網頁的編碼,決定瀏覽器將以什麼形式、什麼編碼讀取這個文件。
好比輸出圖片文件、JSON數據、XML文件等非HTML內容時,就必須用header函數來指定Content-Type,才能達到輸出一張圖片或是其它指定內容類型的需求。
下面列舉一些經常使用的內容類型:
文件擴展名 | Content-Type(Mime-Type) | 描述 |
---|---|---|
application/pdf | PDF(Portable Document Format的簡稱,意爲「便攜式文件格式」) | |
.json | application/json | JSON(JavaScript Object Notation) |
.js | application/javascript | ECMAScript/JavaScript(至關於application/ecmascript可是寬鬆的處理規則) |
.xml | application/xml | 可擴展標記語言(英語:eXtensible Markup Language,簡稱: XML),是一種標記語言。 |
.zip | application/zip | ZIP壓縮文件 |
.gzip | application/gzip | Gzip是若干種文件壓縮程序的簡稱,一般指GNU計劃的實現,此處的gzip表明GNU zip。 |
.csv | text/csv | 逗號分隔值(Comma-Separated Values,CSV,有時也稱爲字符分隔值,由於分隔字符也能夠不是逗號),其文件以純文本形式存儲表格數據(數字和文本)。 |
.html | text/html | |
.mp3 | audio/mp3 | |
.mp4 | audio/mp4 | MP4,全稱MPEG-4 Part 14,是一種使用MPEG-4的多媒體計算機文件格式,擴展名爲.mp4,以存儲數字音頻及數字視頻爲主。 |
.tif | image/tiff | 標籤圖像文件格式(Tagged Image File Format,簡寫爲TIFF)是一種主要用來存儲包括照片和藝術圖在內的圖像的文件格式。它最初由Aldus公司與微軟公司一塊兒爲PostScript打印開發。 |
.gif | image/gif | 圖像互換格式(GIF,Graphics Interchange Format)是一種位圖圖形文件格式,以8位色(即256種顏色)重現真彩色的圖像。 |
.jpeg | image/jpeg | JPEG是一種針對相片圖像而普遍使用的一種有損壓縮標準方法。 |
.png | image/png | 便攜式網絡圖形(Portable Network Graphics,PNG)是一種無損壓縮的位圖圖形格式,支持索引、灰度、RGB三種顏色方案以及Alpha通道等特性。 |
Spring很早就有導出REST資源的需求。Spring對REST的支持是構建在Spring MVC之上的。從3.0版本開始,Spring針對Spring MVC的一些加強功能對REST提供了良好的支持。
4.0版本中,Spring支持如下方式來建立REST資源:
package org.springframework.web.bind.annotation;
/**
* Java 5 enumeration of HTTP request methods.
* @since 2.5
*/
public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}
複製代碼
Spring 3.2及以上版本還支持PATCH方法。
藉助@PathVariable註解,控制器可以處理參數化的URL(將變量輸入做爲URL的一部分)。
藉助Spring的視圖和視圖解析器,資源可以以多種方式進行表述,包括將模型數據渲染爲XML、JSON、Atom以及RSS的View實現。
可使用ContentNegotiatingViewResolver來選擇最適合客戶端的表述。
藉助@ResponseBody註解和各類HttpMethodConverter實現,可以替換基於視圖的渲染方式。
@RequestBody註解以及HttpMethodConverter實現能夠將傳入的HTTP數據轉化爲傳入控制器處理方法的Java對象。
藉助RestTemplate,Spring應用可以方便地使用REST資源。
經過ResponseEntity對象,能夠封裝HTTP返回的header、body和statusCode。