原文鏈接:http://www.ibm.com/developerworks/cn/java/j-lo-jaxrs/index.htmlREST簡(jiǎn)介REST是英文RepresentationalStateTransfer的縮寫,有中文" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

使用 JAX-RS 簡(jiǎn)化 REST 應(yīng)用開發(fā)

系統(tǒng) 1665 0
<!-- Related_Searches_Area_And_Overlays_Begin --><!-- MAIN_COLUMN_CONTAINER_BEGIN -->
<!-- MAIN_COLUMN_CONTENT_BEGIN -->

?

原文鏈接: http://www.ibm.com/developerworks/cn/java/j-lo-jaxrs/index.html

?

?

REST 簡(jiǎn)介

REST 是英文 Representational State Transfer 的縮寫,有中文翻譯為“具象狀態(tài)傳輸”。REST 這個(gè)術(shù)語是由 Roy Fielding 在他的博士論文 《 Architectural Styles and the Design of Network-based Software Architectures 》 中提出的。REST 并非標(biāo)準(zhǔn),而是一種開發(fā) Web 應(yīng)用的架構(gòu)風(fēng)格,可以將其理解為一種設(shè)計(jì)模式。REST 基于 HTTP,URI,以及 XML 這些現(xiàn)有的廣泛流行的協(xié)議和標(biāo)準(zhǔn),伴隨著 REST,HTTP 協(xié)議得到了更加正確的使用。

相較于基于 SOAP 和 WSDL 的 Web 服務(wù),REST 模式提供了更為簡(jiǎn)潔的實(shí)現(xiàn)方案。目前,越來越多的 Web 服務(wù)開始采用 REST 風(fēng)格設(shè)計(jì)和實(shí)現(xiàn),真實(shí)世界中比較著名的 REST 服務(wù)包括: Google AJAX 搜索 API Amazon Simple Storage Service (Amazon S3) 等。

基于 REST 的 Web 服務(wù)遵循一些基本的設(shè)計(jì)原則:

  • 系統(tǒng)中的每一個(gè)對(duì)象或是資源都可以通過一個(gè)唯一的 URI 來進(jìn)行尋址,URI 的結(jié)構(gòu)應(yīng)該簡(jiǎn)單、可預(yù)測(cè)且易于理解,比如定義目錄結(jié)構(gòu)式的 URI。
  • 以遵循 RFC-2616 所定義的協(xié)議的方式顯式地使用 HTTP 方法,建立創(chuàng)建、檢索、更新和刪除(CRUD:Create, Retrieve, Update and Delete)操作與 HTTP 方法之間的一對(duì)一映射:
    • 若要在服務(wù)器上創(chuàng)建資源,應(yīng)該使用 POST 方法;
    • 若要檢索某個(gè)資源,應(yīng)該使用 GET 方法;
    • 若要更改資源狀態(tài)或?qū)ζ溥M(jìn)行更新,應(yīng)該使用 PUT 方法;
    • 若要?jiǎng)h除某個(gè)資源,應(yīng)該使用 DELETE 方法。
  • URI 所訪問的每個(gè)資源都可以使用不同的形式加以表示(比如 XML 或者 JSON),具體的表現(xiàn)形式取決于訪問資源的客戶端,客戶端與服務(wù)提供者使用一種內(nèi)容協(xié)商的機(jī)制(請(qǐng)求頭與 MIME 類型)來選擇合適的數(shù)據(jù)格式,最小化彼此之間的數(shù)據(jù)耦合。

JAX-RS -- Java API for RESTful Web Services

Java EE 6 引入了對(duì) JSR-311 的支持。JSR-311(JAX-RS:Java API for RESTful Web Services)旨在定義一個(gè)統(tǒng)一的規(guī)范,使得 Java 程序員可以使用一套固定的接口來開發(fā) REST 應(yīng)用,避免了依賴于第三方框架。同時(shí),JAX-RS 使用 POJO 編程模型和基于標(biāo)注的配置,并集成了 JAXB,從而可以有效縮短 REST 應(yīng)用的開發(fā)周期。

JAX-RS 定義的 API 位于 javax.ws.rs 包中,其中一些主要的接口、標(biāo)注和抽象類如 圖 1 所示。


圖 1. javax.ws.rs 包概況

JAX-RS 的具體實(shí)現(xiàn)由第三方提供,例如 Sun 的參考實(shí)現(xiàn) Jersey、Apache 的 CXF 以及 JBoss 的 RESTEasy。

在接下來的文章中,將結(jié)合一個(gè)記賬簿應(yīng)用向讀者介紹 JAX-RS 一些關(guān)鍵的細(xì)節(jié)。


示例簡(jiǎn)介

記賬簿示例應(yīng)用程序中包含了 3 種資源:賬目、用戶以及賬目種類,用戶與賬目、賬目種類與賬目之間都是一對(duì)多的關(guān)系。記賬簿實(shí)現(xiàn)的主要功能包括:

  1. 記錄某用戶在什么時(shí)間花費(fèi)了多少金額在哪個(gè)種類上
  2. 按照用戶、賬目種類、時(shí)間或者金額查詢記錄
  3. 對(duì)用戶以及賬目種類的管理

Resource 類和 Resource 方法

Web 資源作為一個(gè) Resource 類來實(shí)現(xiàn),對(duì)資源的請(qǐng)求由 Resource 方法來處理。Resource 類或 Resource 方法被打上了 Path 標(biāo)注,Path 標(biāo)注的值是一個(gè)相對(duì)的 URI 路徑,用于對(duì)資源進(jìn)行定位,路徑中可以包含任意的正則表達(dá)式以匹配資源。和大多數(shù) JAX-RS 標(biāo)注一樣,Path 標(biāo)注是可繼承的,子類或?qū)崿F(xiàn)類可以繼承超類或接口中的 Path 標(biāo)注。

Resource 類是 POJO,使用 JAX-RS 標(biāo)注來實(shí)現(xiàn)相應(yīng)的 Web 資源。Resource 類分為根 Resource 類和子 Resource 類,區(qū)別在于子 Resource 類沒有打在類上的 Path 標(biāo)注。Resource 類的實(shí)例方法打上了 Path 標(biāo)注,則為 Resource 方法或子 Resource 定位器,區(qū)別在于子 Resource 定位器上沒有任何 @GET、@POST、@PUT、@DELETE 或者自定義的 @HttpMethod。 清單 1 展示了示例應(yīng)用中使用的根 Resource 類及其 Resource 方法。


清單 1. 根 Resource 類
                				
@Path("/") 
public class BookkeepingService { 
    ...... 
    @Path("/person/") 
    @POST 
    @Consumes("application/json") 
    public Response createPerson(Person person) { 
        ...... 
    } 

    @Path("/person/") 
    @PUT 
    @Consumes("application/json") 
    public Response updatePerson(Person person) { 
        ...... 
    } 

    @Path("/person/{id:\\d+}/") 
    @DELETE 
    public Response deletePerson(@PathParam("id") 
    int id) { 
        ...... 
    } 

    @Path("/person/{id:\\d+}/") 
    @GET 
    @Produces("application/json") 
    public Person readPerson(@PathParam("id") 
    int id) { 
        ...... 
    } 

    @Path("/persons/") 
    @GET 
    @Produces("application/json") 
    public Person[] readAllPersons() { 
        ...... 
    } 

    @Path("/person/{name}/") 
    @GET 
    @Produces("application/json") 
    public Person readPersonByName(@PathParam("name") 
    String name) { 
        ...... 
} 
...... 

              

參數(shù)標(biāo)注

JAX-RS 中涉及 Resource 方法參數(shù)的標(biāo)注包括:@PathParam、@MatrixParam、@QueryParam、@FormParam、@HeaderParam、@CookieParam、@DefaultValue 和 @Encoded。這其中最常用的是 @PathParam,它用于將 @Path 中的模板變量映射到方法參數(shù),模板變量支持使用正則表達(dá)式,變量名與正則表達(dá)式之間用分號(hào)分隔。例如對(duì) 清單 1 中所示的 BookkeepingService 類,如果使用 Get 方法請(qǐng)求資源”/person/jeffyin”,則 readPersonByName 方法將被調(diào)用,方法參數(shù) name 被賦值為”jeffyin”;而如果使用 Get 方法請(qǐng)求資源”/person/123”,則 readPerson 方法將被調(diào)用,方法參數(shù) id 被賦值為 123。要了解如何使用其它的參數(shù)標(biāo)注 , 請(qǐng)參考 JAX-RS API 。

JAX-RS 規(guī)定 Resource 方法中只允許有一個(gè)參數(shù)沒有打上任何的參數(shù)標(biāo)注,該參數(shù)稱為實(shí)體參數(shù),用于映射請(qǐng)求體。例如 清單 1中所示的 BookkeepingService 類的 createPerson 方法和 updatePerson 方法的參數(shù) person。

參數(shù)與返回值類型

Resource 方法合法的參數(shù)類型包括:

  1. 原生類型
  2. 構(gòu)造函數(shù)接收單個(gè)字符串參數(shù)或者包含接收單個(gè)字符串參數(shù)的靜態(tài)方法 valueOf 的任意類型
  3. List<T>,Set<T>,SortedSet<T>(T 為以上的 2 種類型)
  4. 用于映射請(qǐng)求體的實(shí)體參數(shù)

Resource 方法合法的返回值類型包括:

  1. void:狀態(tài)碼 204 和空響應(yīng)體
  2. Response:Response 的 status 屬性指定了狀態(tài)碼,entity 屬性映射為響應(yīng)體
  3. GenericEntity:GenericEntity 的 entity 屬性映射為響應(yīng)體,entity 屬性為空則狀態(tài)碼為 204,非空則狀態(tài)碼為 200
  4. 其它類型:返回的對(duì)象實(shí)例映射為響應(yīng)體,實(shí)例為空則狀態(tài)碼為 204,非空則狀態(tài)碼為 200

對(duì)于錯(cuò)誤處理,Resource 方法可以拋出非受控異常 WebApplicationException 或者返回包含了適當(dāng)?shù)腻e(cuò)誤碼集合的 Response 對(duì)象。

Context 標(biāo)注

通過 Context 標(biāo)注,根 Resource 類的實(shí)例字段可以被注入如下類型的上下文資源:

  1. Request、UriInfo、HttpHeaders、Providers、SecurityContext
  2. HttpServletRequest、HttpServletResponse、ServletContext、ServletConfig

要了解如何使用第 1 種類型的上下文資源 , 請(qǐng)參考 JAX-RS API 。


CRUD 操作

JAX-RS 定義了 @POST、@GET、@PUT 和 @DELETE,分別對(duì)應(yīng) 4 種 HTTP 方法,用于對(duì)資源進(jìn)行創(chuàng)建、檢索、更新和刪除的操作。

POST 標(biāo)注

POST 標(biāo)注用于在服務(wù)器上創(chuàng)建資源,如 清單 2 所示。


清單 2. POST 標(biāo)注
                				
@Path("/") 
public class BookkeepingService { 
    ...... 
    @Path("/account/") 
    @POST 
    @Consumes("application/json") 
    public Response createAccount(Account account) { 
        ...... 
    } 
...... 

              

如果使用 POST 方法請(qǐng)求資源”/account”,則 createAccount 方法將被調(diào)用,JSON 格式的請(qǐng)求體被自動(dòng)映射為實(shí)體參數(shù) account。

GET 標(biāo)注

GET 標(biāo)注用于在服務(wù)器上檢索資源,如 清單 3 所示。


清單 3. GET 標(biāo)注
                				
@Path("/") 
public class BookkeepingService { 
    ...... 
    @Path("/person/{id}/accounts/") 
    @GET 
    @Produces("application/json") 
    public Account[] readAccountsByPerson(@PathParam("id") 
    int id) { 
        ...... 
    } 
    ...... 
    @Path("/accounts/{beginDate:\\d{4}-\\d{2}-\\d{2}},{endDate:\\d{4}-\\d{2}-\\d{2}}/") 
    @GET 
    @Produces("application/json") 
    public Account[] readAccountsByDateBetween(@PathParam("beginDate") 
    String beginDate, @PathParam("endDate") 
    String endDate) throws ParseException { 
        ...... 
    } 
...... 

              

如果使用 GET 方法請(qǐng)求資源”/person/123/accounts”,則 readAccountsByPerson 方法將被調(diào)用,方法參數(shù) id 被賦值為 123,Account 數(shù)組類型的返回值被自動(dòng)映射為 JSON 格式的響應(yīng)體;而如果使用 GET 方法請(qǐng)求資源”/accounts/2008-01-01,2009-01-01”,則 readAccountsByDateBetween 方法將被調(diào)用,方法參數(shù) beginDate 被賦值為”2008-01-01”,endDate 被賦值為”2009-01-01”,Account 數(shù)組類型的返回值被自動(dòng)映射為 JSON 格式的響應(yīng)體。

PUT 標(biāo)注

PUT 標(biāo)注用于更新服務(wù)器上的資源,如 清單 4 所示。


清單 4. PUT 標(biāo)注
                				
@Path("/") 
public class BookkeepingService { 
    ...... 
    @Path("/account/") 
    @PUT 
    @Consumes("application/json") 
    public Response updateAccount(Account account) { 
        ...... 
    } 
...... 

              

如果使用 PUT 方法請(qǐng)求資源”/account”,則 updateAccount 方法將被調(diào)用,JSON 格式的請(qǐng)求體被自動(dòng)映射為實(shí)體參數(shù) account。

DELETE 標(biāo)注

DELETE 標(biāo)注用于刪除服務(wù)器上的資源,如 清單 5 所示。


清單 5. DELETE 標(biāo)注
                				
@Path("/") 
public class BookkeepingService { 
    ...... 
    @Path("/account/{id:\\d+}/") 
    @DELETE 
    public Response deleteAccount(@PathParam("id") 
    int id) { 
        ...... 
    } 
...... 

              

如果使用 DELETE 方法請(qǐng)求資源”/account/323”,則 deleteAccount 方法將被調(diào)用,方法參數(shù) id 被賦值為 323。


內(nèi)容協(xié)商與數(shù)據(jù)綁定

Web 資源可以有不同的表現(xiàn)形式,服務(wù)端與客戶端之間需要一種稱為內(nèi)容協(xié)商(Content Negotiation)的機(jī)制:作為服務(wù)端,Resource 方法的 Produces 標(biāo)注用于指定響應(yīng)體的數(shù)據(jù)格式(MIME 類型),Consumes 標(biāo)注用于指定請(qǐng)求體的數(shù)據(jù)格式;作為客戶端,Accept 請(qǐng)求頭用于選擇響應(yīng)體的數(shù)據(jù)格式,Content-Type 請(qǐng)求頭用于標(biāo)識(shí)請(qǐng)求體的數(shù)據(jù)格式。

JAX-RS 依賴于 MessageBodyReader 和 MessageBodyWriter 的實(shí)現(xiàn)來自動(dòng)完成返回值到響應(yīng)體的序列化以及請(qǐng)求體到實(shí)體參數(shù)的反序列化工作,其中,XML 格式的請(qǐng)求/響應(yīng)數(shù)據(jù)與 Java 對(duì)象的自動(dòng)綁定依賴于 JAXB 的實(shí)現(xiàn)。

用戶可以使用 Provider 標(biāo)注來注冊(cè)使用自定義的 MessageBodyProvider,如 清單 6 所示,GsonProvider 類使用了 Google Gson 作為 JSON 格式的 MessageBodyProvider 的實(shí)現(xiàn)。


清單 6. GsonProvider
                				
@Provider 
@Produces("application/json") 
@Consumes("application/json") 
public class GsonProvider implements MessageBodyWriter<Object>, 
    MessageBodyReader<Object> { 

    private final Gson gson; 

    public GsonProvider() { 
        gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setDateFormat( 
                "yyyy-MM-dd").create(); 
    } 

    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, 
            MediaType mediaType) { 
        return true; 
    } 

    public Object readFrom(Class<Object> type, Type genericType, 
            Annotation[] annotations, MediaType mediaType, 
            MultivaluedMap<String, String> httpHeaders, InputStream entityStream) 
            throws IOException, WebApplicationException { 
        return gson.fromJson(new InputStreamReader(entityStream, "UTF-8"), type); 
    } 

    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, 
            MediaType mediaType) { 
        return true; 
    } 

    public long getSize(Object obj, Class<?> type, Type genericType, 
            Annotation[] annotations, MediaType mediaType) { 
        return -1; 
    } 

    public void writeTo(Object obj, Class<?> type, Type genericType, 
            Annotation[] annotations, MediaType mediaType, 
            MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) 
            throws IOException, WebApplicationException { 
        entityStream.write(gson.toJson(obj, type).getBytes("UTF-8")); 
    } 

} 

              


JAX-RS 與 JPA 的結(jié)合使用

由于 JAX-RS 和 JPA 同樣都使用了基于 POJO 和標(biāo)注的編程模型,因而很易于結(jié)合在一起使用。示例應(yīng)用中的 Web 資源 ( 如賬目 ) 同時(shí)也是持久化到數(shù)據(jù)庫(kù)中的實(shí)體,同一個(gè) POJO 類上既有 JAXB 的標(biāo)注,也有 JPA 的標(biāo)注 ( 或者還有 Gson 的標(biāo)注 ) ,這使得應(yīng)用中類的個(gè)數(shù)得以減少。如 清單 7 所示,Account 類可以在 JAX-RS 與 JPA 之間得到復(fù)用,它不但可以被 JAX-RS 綁定為請(qǐng)求體 / 響應(yīng)體的 XML/JSON 數(shù)據(jù),也可以被 JPA 持久化到關(guān)系型數(shù)據(jù)庫(kù)中。


清單 7. Account
                				
@Entity 
@Table(name = "TABLE_ACCOUNT") 
@XmlRootElement 
public class Account { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "COL_ID") 
    @Expose 
    private int id; 

    @ManyToOne 
    @JoinColumn(name = "COL_PERSON") 
    @Expose 
    private Person person; 

    @Column(name = "COL_AMOUNT") 
    @Expose 
    private BigDecimal amount; 

    @Column(name = "COL_DATE") 
    @Expose 
    private Date date; 

    @ManyToOne 
    @JoinColumn(name = "COL_CATEGORY") 
    @Expose 
    private Category category; 

    @Column(name = "COL_COMMENT") 
    @Expose 
    private String comment; 
...... 

              


結(jié)束語

REST 作為一種輕量級(jí)的 Web 服務(wù)架構(gòu)被越來越多的開發(fā)者所采用,JAX-RS 的發(fā)布則規(guī)范了 REST 應(yīng)用開發(fā)的接口。本文首先闡述了 REST 架構(gòu)的基本設(shè)計(jì)原則,然后通過一個(gè)示例應(yīng)用展示了 JAX-RS 是如何通過各種標(biāo)注來實(shí)現(xiàn)以上的設(shè)計(jì)原則的,最后還介紹了 JAX-RS 與 JPA、Gson 的結(jié)合使用。本文的示例應(yīng)用使用了 Jersey 和 OpenJPA,部署在 Tomcat 容器上,替換成其它的實(shí)現(xiàn)只需要修改 web.xml 和 persistence.xml 配置文件。

<!-- CMA ID: 426622 --><!-- Site ID: 10 --><!-- XSLT stylesheet used to transform this file: dw-article-6.0-beta.xsl -->

下載

描述 名字 大小 下載方法
本文示例代碼 Bookkeeping.zip 24 KB HTTP

使用 JAX-RS 簡(jiǎn)化 REST 應(yīng)用開發(fā)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!??!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: www九色 | 国内一级一级毛片a免费 | 狠狠操天天操 | 欧美一区二区三区在观看 | 婷婷精品国产亚洲AV在线观看 | 天天操天天射天天舔 | www.75zzz.com| 国内精品免费视频 | 这里只有精品在线视频观看 | 青娱乐免费视频在线观看 | 亚洲一区二区三区视频 | 99re6在线| 欧美成年 | a久久| 天天干天天插天天 | 国产成人精品一区二区仙踪林 | 精品免费视频 | 九一精品 | 精品一区二区三区的国产在线观看 | 天天骑天天干 | www.中文字幕在线观看 | 国产99精品| 欧美大香线蕉线伊人久久 | 日韩一区二区免费看 | 欧美不卡一区二区三区在线观看 | www.99热| 久久久国产视频 | 日韩精品一区二区在线观看 | 久久久不卡网国产精品一区 | www.久久久.com | 精品一卡2卡三卡4卡免费视频 | 亚洲精品久久久久一区二区三 | 免费一区 | 亚洲国产精品久久 | 毛片国产 | 国产日韩欧美中文字幕 | 91av视频在线 | 亚洲欧美久久婷婷爱综合一区天堂 | 亚洲国产婷婷香蕉久久久久久99 | 狠狠色依依成人婷婷九月 | 天天爽天天干天天操 |