【51CTO精選譯文】上周我們介紹了Java EE 6平台的主要目標,本篇介紹這個版本中引入的新技術。這些新技術使這個平台變得更加強大,其中三個重要的新技術包括:51CTO編輯推薦您閱讀《Java EE 6平台指南》專題了解更多。
◆RESTful Web Services Java API (JAX-RS)
◆面向Java EE平台的上下文和依賴性注入(CDI)
◆Bean驗證
本文將介紹RESTful Web Services Java API (JAX-RS)。
RESTful Web Services Java API (JAX-RS)
RESTful Web Services Java API (JAX-RS),JSR 311讓你可以迅速構建遵循REST(Representational State Transfer,表象化狀態轉變。參考閱讀:《什麼是REST》)風格軟件架構的輕量級Web服務。REST中的一個重要概念是資源的存在性,每個資源都一個全局引用標識符,即URI。特別是數據和函數都被認為是可通過URI識別和訪問的資源。為了操縱這些資源,網絡組件,客戶端和服務器通過一個標准的接口通信,如HTTP和一個組固定的動詞 — GET,PUT,POST和DELETE — 交換這些資源。
RESTful Web服務是按照REST架構風格構建的Web服務,利用RESTful方法使用基於SOAP的技術構建Web服務已經成為一個受歡迎的選擇,這都得感謝REST的輕量級特性和直接通過HTTP傳輸數據的能力。
JAX-RS為在Java中構建RESTful Web服務提供了標准化API,API提供了一組注解,以及相關的類和接口。對POJO應用注解允許你暴露Web資源,這個方法使得在Java中創建RESTful Web服務變得簡單。
JAX-RS 1.0技術規范定稿於2008年10月,包括了一個參考實現Jersey,Java EE 6包括了這個技術規范的最新版本JAX-RS 1.1,這個版本與Java EE 6中的新特性保持一致。
下面我們一起來看一個使用JAX-RS構建的RESTful Web服務:
- import Javax.ws.rs.Path;
- import Javax.ws.rs.Produces;
- import Javax.ws.rs.Get;
- import Javax.ws.rs.Post;
- import Javax.ws.rs.Consumes;
- import Javax.ws.rs.core.Response;
- import Javax.ws.rs.core.MediaType;
- import Javax.ws.rs.core UriInfo;
- import Javax.ws.rs.core.UriBuilder;
- import Java.Net.URI;
- @Path ("items")
- @Produces (MediaType.APPLICATION_XML)
- Public class ItemsResource {
- @Context UriInfo uriInfo;
- @GET
- Items listItems() {
- Return Allitems();
- }
- @POST
- @Consumes (MediaType.APPLICATION_XML)
- Public Response create(Item item) throws ItemCreationException {
- Item newItem = createItem(item);
- URI newItemURI = uriInfo.getRequestUriBuilder().path(newItem.getId()).build();
- return Response.created(newItemURI).build();
- }
- ...
- }
在這個例子中,ItemsResource類是管理一組項目的Web服務,類中導入了JAX-RS 1.1注解,類和接口。
@Path注解指定了資源的相對路徑,在這裡是“items”,類資源URI是基於應用程序上下文的,因此,如果應用程序上下文在這個例子中是http://example.com,那麼類資源的URI就是http://example.com/items,這意味著如果一個客戶端直接請求URI http://example.com/items,ItemsResource類將會執行。
@GET注解指定了注解的方法,這裡是listItems()方法,它處理HTTP GET請求,當某個客戶端直接發起對ItemsResource資源的HTTP GET請求時,JAX-RS運行時調用listItems()方法處理這個GET請求。
注意@Produces注解,它指定了返回給客戶端的MIME媒體類型,在ItemsResource這個例子中,@Produces注解指定了MediaType.APPLICATION_XML,MediaType類是一個抽象的MIME媒體類型,MediaType.APPLICATION_XML是XML內容MIME媒體類型的抽象 — application/XML。
注解如@Produces建議JAX-RS自動轉換某些內容類型,例如,listItems()方法返回一個Items類型的Java對象,JAX-RS自動將這個Java類型轉換成application/XML MIME類型,使用這個MIME類型響應客戶端的HTTP請求。注意僅當返回的類型默認是支持的才會自動轉換,例如,如果Items是一個JAXB注解Bean,那麼將會自動轉換,但如果Items是一個POJO,你需要執行MessageBodyReader處理序列化。
你也可以在一個方法上指定@Produces注解,在上面的例子中,你在方法上指定的MIME類型覆蓋了在類的@Produces注解中指定的MIME類型,例如,你可以象下面這樣為listItems()方法指定@Produces注解:
- @GET
- @Produces (MediaType.TEXT_PLAIN)
- Items listItems() {
- Return Allitems();
- }
JAX-RS然後會將Items Java類型轉換為text/plain MIME類型,返回這種類型的內容給HTTP請求客戶端。
@POST注解指定了注解的方法,這裡是create()方法,它負責響應HTTP POST請求。在這個例子中,這個方法創建了一個新項目,然後返回一個表示它已創建了一個新項目的響應,當客戶端直接向ItemsResource資源發起HTTP POST請求時,JAX-RS運行時調用create()方法處理POST請求。
注意@Consumes注解是在create()方法上指定的,注解指定了方法能夠接受的來自客戶端的MIME媒體類型。如果你在類上指定@Consumes,它適用於類中的所有方法,如果你在方法上指定@Consumes,它會覆蓋你在類上指定的@Consumes注解包含的MIME類型。在這個例子中,@Consumes注解指定create()方法可接受XML內容,即MIME類型application/xml,這是從MIME類型轉換到Java類型。當某個客戶端在POST請求中提交XML內容時,JAX-RS調用create()方法自動將傳入的XML內容轉換成方法需要的Item Java類型。
JAX-RS也包括大量的進一步簡化有關構建行為的實用類和接口,前面看到的MediaType就是這樣的類,它抽象了MIME媒體類型。其它的一些類和接口是:
UriInfo:訪問URI信息的接口,在這個例子中,@Context注解注入UriInfo接口到ItemsResource類中的uriInfo字段。
UriBuilder:從它們的組件構建URI的類。
Response:代表HTTP響應的類。
Response.ResponseBuilder:根據著名的Builder模式構建Response對象的類。
這些類和接口在下面這些語句中非常有用:
- URI newItemURI = uriInfo.getRequestUriBuilder().path(newItem.getId()).build();
- return Response.created(newItemURI).build();
第一個語句為新項目構建一個URI,getRequestUriBuilder()方法是創建UriBuilder對象的UriInfo方法,path() 和 build()方法是為新項目一起構造URI的UriBuilder方法。
這些實用類和接口隱藏了HTTP編程的許多復雜性,使用JAX-RS的另一個原因是它簡化了構建RESTful Web服務,JAX-RS可以簡化許多類型的Web應用程序,例如,如果你需要構建一個檢查HTTP頭的應用程序,JAX-RS比采用其它技術就更簡單。
JAX-RS還有其它便捷功能,例如,JAX-RS包括大量基於參數的注解,從請求中提取信息,@QueryParam就是這樣的注解,通過它你可以從請求URL中的Query組件提取查詢參數,其它基於參數的注解還有@MatrixParam,它從URL路徑提取信息,@HeaderParam注解從HTTP頭提取信息,@CookieParam從CookIEs提取信息。