开发RESTful web Service

来源:互联网 发布:java 小红本 编辑:程序博客网 时间:2024/05/21 22:26

开发RESTful webService

chapter1:介绍RESTful Web Services

表征状态传输(Representational State Transfer(REST) )是一个软件架构风格,该架构围绕Http协议上数据的传输,使用http的那四个谓词:get,put,serice.delete.这个架构也避免了对诸如:SOAP envelope这样的附加包装器的使用以及任何状态数据的使用。

概要:REST是一个架构风格,首次在一个博士论文中被描述,该博士是Roy Fielding。在RESTful系统中,服务器利用URI暴露资源,客户端使用四个Http谓词来访问资源。由于客户端接收了资源,他们被置于某种状态。当他们访问一个新的资源,通常是点击下一个连接,他们改变了,或者说是过渡了他们的状态。为了工作,REST假设资源是能够使用普遍的标准语法来代表的。

3W网络是最普及的例子,他是最大的基于REST策略构建的系统。web浏览器作为客户端访问驻留在web服务器上的资源。资源通过HTML或者xml体现,所有的web浏览器可以消费它。浏览器可以很容易的根据连接跳转到新的资源上面。

RESTful系统的优势在于他们可以高伸缩性和高灵活性。因为被访问和操作的资源是通过http谓词。资源通过URI被暴露,资源被通过标准的语法体现,客户端不会被服务器所影响。也就是说,RESTFul系统可以充分体现http的可伸缩性特性,比如:缓存和代理特性。

基础REST策略:RESTful架构坚持下面的基本原则:

  • 应用程序状态和功能被分离到不同资源中。
  • 资源是可以定位的通过标准URLs,并且这个URLs可以作为超媒体连接。
  • 所有资源可以被http谓词所使用:delete,get,post,put
  • 所有资源提供信息通过MIME类型(该类型被HTTP支持)
  • 协议是无状态的
  • 协议是可缓存的
  • 协议是分层的

 

资源:资源是REST的中心,一个资源是信息源,可以被URI来标注的。在web的早期,资源是大量的静态文档,在当下,一个资源可以是任何信息源,例如web Service可以是一个资源如果他能够通过一个URI来被访问。

RESTful端点交换他们代表的资源。一个代表可以使一个包含了数据的文档。例如:web Service的方法提供了访问客户的记录,那么该方法就是资源,在服务和消费者之间传输的客户信息拷贝,也是资源的代表。

REST最佳实践:当设计一个RESTful服务时,最佳实践有如下帮助:

  • 提供一个不一样的URI给每个你希望暴露的资源。

        例如:如果你在建立一个系统,该系统处理驾驶记录,每个记录将有个唯一的URI,如果这个系统提供违规停车和超速罚款记录,每个资源的类型应该也有一个唯一的基准。例如:超速罚款应该通过/speedingfines/driverID来访问,而违规停车应该通过/parkingfines/driverID来访问。

  • 在URIs中使用声明:使用nouns突出显示资源是事情而不是动作这件事实。URLs诸如:/ordering隐喻了行为,而/orders隐喻了事情
  • get对应的方法应该不去改变任何数据。
  • 在应答里使用链接:

          放入去向别的资源的链接到应答里,可以使客户端跟从一个数据链变得容易。例如,如果你的服务返回一个资源集合,对于客户单来说,更容易访问每个独立的资源,使用提供的连接,如果连接不被包含在response里面,客户端需要附加的逻辑来跟从这个去向特定节点的连接。

 

  • 使服务无状态

         需要客户端或者服务端维护状态信息,导致两者的紧耦合,紧耦合会让升级和迁移变得更困难。维护状态也会使从通信错误中还原状态变得更麻烦。

设计一个RESTful web Service:

         要执行以下步骤:

  1. 定义服务将要暴露的资源:通常,一个服务将暴露一个或多个资源,这些资源会组织成一个树,例如:一个驾驶记录服务被组织成三个资源:/license/driverID ,/license/driverID/speedingfines,/license/driverID/parkingfines
  2. 定义在每个资源上执行的动作,例如:你可能想更新驾驶员地址或者删除停车罚单从一个驾驶员记录中。
  3. 映射行为到何时的http谓词。

一旦你定义好了服务,你就可以使用FUSE Services Framework去实现它了。

采用Fuse Services Framework实现REST

           FSF提供RESTful Web Service的java API的实现。JAX-RS提供标准的方式去映射POJO到资源中去,使用annotations。

当从一个抽象的服务定义转移到使用JAX-RS实现RESTFul Web Services实现,你需要做:

    1.创建根资源类给资源,该根资源类代表了服务资源树的顶端。

    2.映射服务的其他资源到树的子资源节点上。

    3.创建方法来实现每个http谓词。

Data bindings:

        默认情况下,FSF使用JAXB对象来映射资源与他的java object。提供清晰,定义良好的映射,在对象和xml元素之间。

      FSF实现也支持交换数据采用JSON,JSON是一种被Ajax开发者广泛使用的数据格式。在json和jaxb之间数据的编组被FSF运行时动态处理。

 

chapter2:创建资源

在RESTFul web Service中,所有的请求被资源所处理。JAX-RS API上实现了将资源看成java类。一个资源类是一个Java类,他被一个或多个RAX-RS注解所标注。用JAX-RS实现的一个RESTFul web Service的核心是一个根资源类。根资源类是被暴露的服务的资源树的入口点。他可以自己处理所有的请求,或者他可以提供对子起源的访问通道。

 介绍:使用JAX-RS APIs实现的RESTFul WEb Services提供应答作为资源代表,该代表实现了java类。一个资源类是一个类,该类使用了JAX-RS注解来实现一个资源。对于大多数RESTful web services来说,他就是一个需要被访问的资源集合。资源类的注解提供了信息诸如:资源的URI和每个操作处理的谓词。

资源类型:JAX-RS APIs允许你创建两个基本类型的资源:

  • 根资源类:是服务资源树的入口点,他被装饰(用@path注解),用以定义服务中资源的基准URI。
  • 子资源:通过根资源来访问的资源,他们被装饰了@path注解的方法所实现。一个子资源的@path注解定义了相对于基准URI的路径。

例子:简单资源类:

package demo.jaxrs.server;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.PathParam;@Path("/customerservice") public class CustomerService{  public CustomerService()  {  }  @GET   public Customer getCustomer(@QueryParam("id") String id)  {    ...  }  ...}

基本的JAX-RS 注解
 

概述:

RESTful web service实现最最基本的信息片是:

  • 服务资源的URI
  • 一个class的方法如何被映射到http谓词上。

JAX-RS定义了一组注解来提供基本的信息。所有的资源类必须有至少一个注解。

设置路径:

@path注解指明了一个资源的URI,该注解定义在Javax.ws.rs.Path接口中。它既可以用来包装一个资源类,也可以用来包装一个资源的方法。它用一个字符串作为唯一参数(可参看上面的代码)。该字符串是一个URI的形式,指明了被实现资源的location。

URI模板指明了资源的相对路径,如下所示:模板包括

  • 未处理的路径组件
  • 被{}包围的参数指示符:参数指示符可以包括通常的表达式来替换缺省的路径

@Path("resourceName/{param1}/../{paramN}")

例如:URI模板:widgets/{color}/{number}将映射到widgets/blue/12.参数color的值是blue,number参数的值是12.

URI模板怎样映射到一个完整的URI,依赖于@Path注解包装的是什么东东,如果@path在根资源类中(注解包装的是根资源类),那么URI模板是所有资源的根URI,并且他被直接添加到服务发布的URI中。如果注解是封装一个子资源类,它将相对于根资源的URI。

指定HTTP 谓词:JAX-RS使用五个注解来指定http谓词,这些谓词使用在方法上。

  • javax.ws.rs.DELETE指明了方法映射到DELETE
  • javax.ws.rs.GET指明方法映射到GET
  • javax.ws.rs.POST指明方法映射到post
  • javax.ws.rs.PUT指明方法映射到put
  • javax.ws.rs.HEAD指明方法映射到HEAD

当映射方法到http谓词,你必须确保映射是有意义的。例如,入股你映射一个要提交订单的方法,你应当映射他到一个put或者post谓词。如果映射它到一个get或者delete谓词,将导致不可以预计的情况发生。

根资源类:

概述:根资源类是一个JAX-RS实现的RESTful服务的入口点,它被@path包装,指示出组成服务的所有资源的根URI。他的方法直接实现在资源上的操作或者提供一个访问其他子资源的通道。

需求:一个类为了成为根资源类,它必须符合下面的规则:

  • 类必须被@path包装

         指定的路径是根URI对于所有实现服务的资源来说。如果根资源类指明它的路径是wiggets并且一个方法实现了GET谓词,然后一个在wedgets上的GET调用将调用该方法。如果子资源指明了他的URI是{id},那么完整的URI模板对于子资源来说,就是widgets/{id},并且他将处理形如widgets/12和widgets/42这样的请求。

  • 类必须有一个公用的构造器用于运行时被调用

        运行环境必须能够提供构造器所需的所有参数。构造器的参数可以包括被JAX-RS参数注解包装的参数。

  • 至少有一个类方法必须被HTTP谓词注解所包装或者被@path所包装

下例现实了一个根资源类提供一个访问子资源类的通道:

package demo.jaxrs.server;import javax.ws.rs.DELETE;import javax.ws.rs.GET;import javax.ws.rs.POST;import javax.ws.rs.PUT;import javax.ws.rs.Path;import javax.ws.rs.PathParam;import javax.ws.rs.QueryParam;import javax.ws.rs.core.Response;@Path("/customerservice/") public class CustomerService{  public CustomerService()   {    ...  }  @GET   public Customer getCustomer(@QueryParam("id") String id)  {    ...  }  @DELETE  public Response deleteCustomer(@QueryParam("id") String id)  {    ...  }  @PUT  public Response updateCustomer(Customer customer)  {    ...  }  @POST  public Response addCustomer(Customer customer)  {    ...  }  @Path("/orders/{orderId}/")   public Order getOrder(@PathParam("orderId") String orderId)  {    ...  }}

resource 方法的工作原理
 

概述:资源方法被JAX-RS注解所注释。他们有HTTP方法注解之一来指明方法处理哪种类型的请求,JAX-RS放置了约束在资源方法上。

普通约束:所有的资源方法必须符合以下条件

  • 必须是public的
  • 必须被HTTP方法注解所包装
  • 不能有多于一个的实体参数

参数:资源方法参数采取两种形式:

  • 实体参数-实体参数是无注解的,他们的值和request的body对应,一个实体参数可以使任意类型的,所以应用城西得有一个实体提供器。通常是JAXB对象。
  • 被注解的参数:被注解的参数使用一个JAX-RS注解来指明参数值是如何映射到请求的。通常,参数值映射的是request URI的一部分。

如下例:实现了一个资源方法,它具有有效的参数列

@POST@Path("disaster/monster/giant/{id}")public void addDaikaiju(Kaiju kaiju,                        @PathParam("id") String id){  ...}

如下例,实现了一个资源方法,他具有无效的参数列
 

@POST@Path("disaster/monster/giant/")public void addDaikaiju(Kaiju kaiju,                        String id){  ...}

返回值:资源方法可以返回以下类型的值

  • void
  • 任何java class:如果是返回javaclass,那么应用程序必然有一个实体提供者。
  • 一个Response。
  • 一个GenericEntity<T>类型的对象

所有的资源方法返回一个HTTP状态代码给请求端。当方法的返回类型是void或者返回值是null时,资源方法设置状态代码为200,当资源方法返回值不是null,它设置状态值为204.

子资源的工作原理

概述:实际情况下,一个服务要处理很多资源。例如,在一个订单处理服务的最佳实践中,支持每个客户作为唯一资源来被处理,每个订单也作为唯一资源来被处理。

使用JAX-RS APIs,可以将客户资源和订单资源作为子资源来处理。一个子资源就是要通过根资源才能访问的资源。通过增加@path注解到一个类方法来定义一个资源是子资源。子资源可以由两条途径来实现:

  • 子资源方法-直接实现一个http谓词,被一个注解所包装
  • 子资源定位-只想一个实现子资源的类

说明子资源:子资源通过用@path包装一个方法来指明。子资源的URI结构如下:

1.追加子资源的@path注解值到子资源的父资源的@path注解值后面。

   父资源的@path注解也许被找到在资源类的一个方法哪里,该方法返回一个对象,该对象包含了子资源。

2.重复前面的步骤直到根资源被触及。

3.被组装的URI被追加到基准URI上。

0 0