JAX-RS入門 九: 內容約定(1)

通常一個SOA的應用都需要足夠的靈活,以便於各種不同的客戶端或平臺進行集成與交互。 RESTful 服務在這方面相當有優勢,因爲大部分的程序語言都能夠與HTTP協議間相互通信。

 

不過這還不夠,爲了高效的運行,不同的用戶可能有不同的需求。例如Java用戶端更多的希望他們的數據是xml格式的;Ajax用戶端則更喜歡JSON格式;Ruby用戶需要想要YAML格式。另外,有時他們還希望這些數據是經過的國際化的,這樣他們可以提供翻譯好的信息給不同的,例如英語、中文、日文、西班牙文或法文用戶。最後,隨着RESTful應用的不斷髮展,老用戶也需要一個簡單的方法來與新版本的服務進行交互。

 

HTTP協議有很多手段可以幫助解決這些集成問題。一個最強大的功能就是用戶可以告訴服務器他們希望的返回格式,客戶端和服務器可以約定好消息體的內容格式,例如:它是怎麼編碼的;它需要返回哪種語言格式等。這種協議被稱爲HTTP Content Negotiation(HTTP內容約定),簡稱conneg。 這節主要介紹conneg是怎麼工作的,JAX-RS怎麼支持它以及在你的應用中協調這些特性有多重要。

 

一、Conneg

 

* Media Type

  

當請求服務端信息時,用戶可以指定他們希望的返回的Media Type,這是通過客戶端設置的Accept 請求頭來實現的,其中Accept的主體部分以逗號分隔。例如:

Java代碼  收藏代碼
  1. GET http://example.com/stuff  
  2. Accept: application/xml, application/json  

上例中,客戶端要求服務端以XML或JSON的格式返回對/stuff的請求。如果服務器不能提供期望的返回格式,則會得到一個406(Not Acceptable)響應碼;否則服務器端選擇其中的一種返回格式,將響應結果發回給客戶端。

 

在Accept中還支持通配符和Media Type屬性,例如:

Java代碼  收藏代碼
  1. GET http://example.com/stuff  
  2. Accept: text/*, text/html;level=1  

text/*表示任何text格式。

 

* Media Type優先級

 

HTTP協議有隱式和顯式選擇返回的Media Type規則。

 

        > 隱式規則

隱式規則就是越具體的Media Type總是優先於越寬泛的規則,例如:

 

Java代碼  收藏代碼
  1. GET http://example.com/stuff  
  2. Accept: text/*, text/html;level=1, */*, application/xml  

服務器端會假設客戶端總是想要一個具體的,而不是寬泛的響應類型,因此以上Accept的Media Types的順序如下:

Java代碼  收藏代碼
  1. 1. text/html;level=1  
  2. 2. application/xml  
  3. 3. text/* 
  4. 4. */*  

因爲text/html;level=1最具體的,因爲排第一;然後是application/xml,因爲它沒有任何屬性定義;然後是text/*和*/*都是寬泛定義,但是相對*/*來說,text/*更具體一些。

 

        > 顯式規則

客戶端也可以通過使用MIME type的q屬性來指定優先順序,q的值域爲0.0到1.0,如果未指定,則缺省值被假設爲1.0。例如:

 

 

Java代碼  收藏代碼
  1. GET http://example.com/stuff  
  2. Accept: text/*;q=0.9, */*;q=0.1, audio/mpeg, application/xml;q=0.5  

如上的順序爲:

Java代碼  收藏代碼
  1. 1. audio/mpeg  
  2. 2. text/* 
  3. 3. application/xml 
  4. 4. */*  

  

二、語言約定

 

客戶端使用Accept-Language頭來指定他們需要接收哪個語種,例如:

Java代碼  收藏代碼
  1. GET http://example.com/stuff  
  2. Accept-Language: en-us, es, fr  

 

這裏用戶希望響應內容爲英語、西班牙語或法語。Accept-Lauguage頭使用編碼格式來指定,以兩個字母代碼表示某種語言,其中這些代碼與語言的映射在ISO-639*標準中定義;除此之處,還可以增加兩個字母更具體的指定是哪個國家的那種語言,例如en-US表示美國英語。

 

另外Accept-Language頭也支持q參數來指定優先級,例如:

Java代碼  收藏代碼
  1. GET http://example.com/stuff  
  2. Accept-Language: fr;q=1.0, es;q=1.0, en=0.1  

對於服務器端的響應,則使用: Content-Language 。來告訴客戶端返回內容的語種。 

 

 

三、壓縮約定

 

爲了節省帶寬,HTTP協議也支持內容壓縮。最通用的壓縮算法就是GZIP。客戶端可以指定Accept-Encoding頭來指定他們支持哪種壓縮算法,例如:

 

Java代碼  收藏代碼
  1. GET http://example.com/stuff  
  2. Accept-Encoding: gzip, deflate  

這裏客戶端說他希望響應內容是以gzip壓縮或者乾脆是不壓縮的。

 

Accept-Encoding也支持q參數,來指定選擇的優先級:

 

Java代碼  收藏代碼
  1. GET http://example.com/stuff  
  2. Accept-Encoding: gzip;q=1.0, compress;0.5; deflate;q=0.1  

  

對於服務器端的響應,則使用: Content-Encoding 。來告訴客戶端返回內容的壓縮算法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章