首页 > 其他 > 详细

RESTful和JAX-RS

时间:2015-09-25 18:30:25      阅读:406      评论:0      收藏:0      [点我收藏+]

简介

  Java Web有很多成熟的框架,主要可以分为两类Web Application和Web Services。用于Web Application的框架包括官方的Servlet/JSP, JSTL/JSF以及第三方Struts/Spring MVC(action-based)。Web Services的项目又可以分为基于XML的(SOAP/WSDL)的和基于JSON的,Java Communitiy为这两种方式都定义了标准,Java EE5引入了JAX-WS(Java API for XML Web Services)-JSR224,Java EE6引入了JAX-RS(Java API for RESTful Web Services)-JSR331。RESTful Service由于轻量,好测试,有弹性等特点,越来越受欢迎。Jersey,RESTEasy都是JAX-RS标准的具体实现。

 

REST

Rest(representational state transfer, 表现层状态转化)是一种渐渐变成Web设计主流的设计理念,最早由Roy Thomas Fielding(HTTP1.0/1.1协议主要设计者之一,Apache作者之一,Apache基金会第一任主席)在2000年的博士论文中提出。

  • 资源(Resource):网络上一个实体(具体信息),每个资源都用一个URI来标识和定位。所有的资源都位于服务器中。
  • 表现层(Representation):资源的表现形式。例如文本信息可以用Txt展现,也可以用HTML,XML,JSON格式表现,甚至是二进制格式。URI只代表资源实体,它的表现形式在Http请求头中用Accept和Content-Type字段指定,这两个字段才是对表现层的描述。客户端见到的所有东西都只是服务器上资源的表现层,客户端和服务器之间传递的也都是表现层(资源请求携带的参数,返回的JSON,TXT,JPG等MIME-TYPE)。
  • 状态转换(State Transfer):客户端所有操作本质上就是用某种方法让服务器中的资源状态发生变化。客户端只能见到资源的表现层,所以服务器上资源状态的转换必然建立在表现层上。客户端让服务器资源发生状态变化的唯一方法就是使用HTTP请求,通过HTTP请求的不同方法(Method)实现对资源的不同的状态更改操作(如增删改查Create,Read,Update,Delete)。HTTP协议中设计的请求方法包括GET(获取),POST(新增),PUT(更新),DELETE(删除),HEAD,STATUS,OPTIONS等,不同方法代表了不同的操作,但是HTML只实现了GET和POST。

 

示例,例如有一个图书管理的Restful服务,该服务将会呈现为下面的形式(先不用考虑服务具体如何实现的):

资源:
  系统中所有书籍的集合是一个资源,可以用URL http://www.example.com/books 来表示   系统中有本书id为1000,这本书也是一个资源,可以用URL http://www.example.com/books/1000 来表示
操作:
  如果想要查看书集中包含哪些具体的书,可以使用GET方法请求集合资源:
    GET http:
//www.example.com/books   如果想要查看id为1000这本书的详细信息,可以GET方法请求单本书的资源:
    GET http:
//www.example.com/books/1000   如果想新增一本书,可以使用POST方法请求集合资源(假如成功后自动生成id为1001):
    POST http:
//www.example.com/books { {‘name‘ : ‘ good book‘}, {‘price‘: 100}}   如果想修改一本书,可以使用PUT方法请求书的资源:
    PUT http:
//www.example.com/books/1001 { {‘price‘: 98} }   如果想删除id为1000的书,可以使用DELETE方法请求单本书的资源:
    DELETE http:
//www.example.com/books/1000

 

特别说明

  • URI中不应该包含动词。资源表示的一种实体,应该都是名词。只能用HTTP请求方法表示资源操作动作。

    例如/posts/show/1 应该改为/posts/1  用GET方法表明是show操作。

  • 有些难以用请求方法直接表达的动作可以换成名词,作为服务性的资源。

    例如 transfer动作   可以修改为POST /transaction  from=1&to=2&amout=100.00

    例如

      http://www.example.com/app/1.0/foo

      http://www.example.com/app/2.0/foo

    在请求头中区分:

      Accept: vnd.example-com.foo+json; version=1.0

      Accept: vnd.example-com.foo+json; version=2.0

 

JAX-RS

JAX-RS和所有JAVA EE的技术一样,只提供了技术标准,允许各个厂家有自己的实现版本,实现版本有:RESTEasy(JBoss), Jersey(Sun提供的参考实现), Apache CXF, Restlet(最早的REST框架,先于JAX-RS出现), Apache Wink。JAX-RS基于JavaEE的Servlet。标准中定义的注解大大简化资源位置和参数的描述,仅仅使用注解就可以将一个POJO java类封装成一个Web资源。JAX-RS也有类似于Spring依赖注入的方式,减少类之间的耦合度。

 

JAX-RS标准的一个简单RESTful Web Service示例,例如有一个greeter的资源,URI为http://localhost:8080/greeter/

@Path("/greeter")   
public class GreeterResource {
    @GET
    @Path("/{name}")
    public String sayHello(@PathParam("name") String name) {
        return "Hello, " + name;
    }
    @DELETE
    @Path("/{name}")
    public String sayBye(@PathParam("name") String name) {
        return "Bye, " + name;
}
}

使用GET方法请求该资源 (http://localhost:8080/greeter/tom)

将得到输出:   Hello, tom

使用DELETE方法请求该资源 (http://localhost:8080/greeter/lily)

将得到输出: Bye, lily

 

如果把上面的资源类定义为接口, 将REST服务的定义和实现分离是一种更好的实现方式。代码更简洁清晰,后期修改也更方便。

 

 

JAX-RS注解

资源类或方法的相对路径注解

@Path

  若希望一个Java类能够处理REST请求,则这个类必须至少添加一个@Path("/")的annotation;对于方法,这个annotation是可选的,如果不添加,则继承类的定义。

  Path里的值可以是复杂表达式,例如@Path("{id}"),其中的{xxx}表示一个模板参数,模板参数是定义在@Path里的通配符,它以 { 开始,中间是一堆字母和数字的混合串(不能包含 字符),以} 结尾。又如: @Path("{firstName}-{lastName}") 

  Path也支持正则表达式,例如:@Path("{id: \\d+}") 

  优先级检查规则(如果这样的规则还不能解决问题,那就是设计的过于复杂了):

    • 首先检查匹配的字符个数,越多越优先;
    • 其次检查内嵌的模板表达式个数,越多越优先;
    • 最后检查非缺省模板表达式个数(缺省模板即未定义正则表达式的模板)

       例如

    1. /customers/{id}/{name}/address  
    2. /customers/{id : .+}/address  
    3. /customers/{id}/address  
    4. /customers/{id : .+}  

 

  Path的字符(如果Path中的表达式包含需要转义的字符,JAX-RS会自动进行转义;否则会认为以及进行过URL Encoding)

    •   允许a-z, A-Z, 0-9
    •   允许_-!.~‘()*
    •   保留(需转义),;:$$+=?/[]@
    •   其字符都需要用%HH转义

 

  子资源定位符(Subresource Locators),一个指定了@Path注解但未指定HttpMethod注解的方法,该方法可以返回另一个资源类对象,让这个对象接着分发和处理请求子资源的请求。子资源类并不需要作为服务对外暴露,所以类上可以不用加@Path注解。

@Path("/customers")
public class CustomerResource {
  ......
  @Path("{database}-db")
  public CustomerResource getDatabase(@PathParam("database") String db) {
    // find the instance based on the db parameter
    CustomerResource resource = locateCustomerResource(db);
    return resource;
  }
  protected CustomerResource locateCustomerResource(String db) {
    ...
  }
  ...... }
public class CustomerResource {  @GET   @Path("{id}")   @Produces("application/xml")   public StreamingOutput getCustomer(@PathParam("id") int id) {     ...   }   @PUT   @Path("{id}")   @Consumes("application/xml")   public void updateCustomer(@PathParam("id") int id, InputStream is) {     ...   } }

  完全动态分发。上面的例子中指定了@Path注解但未指定HttpMethod注解的方法,该方法可以返回任何类对象。JAX-RS会检查这个对象并自动决定如何分发和处理请求。

@Path("{database}-db")
  public Object getDatabase(@PathParam("database") String db) {
    if(db.equals("europe"))
      return locateCustomerResource(db);     return "not supported db";   }

 

 

请求方法注解

@GET, @PUT, @POST, @DELETE    方法可以处理的HTTP请求方法类型

  一个方法只有添加了请求方法注解,才能处理请求。

  可以自定义请求方法注解,但不要重写HttpMethod定义的注解(GET,POST,PUT,DELETE,HEAD,OPTIONS)

@Target({ElementType.METHOD})  
@Retention(RetentionPolicy.RUNTIME)  
@HttpMethod("LOCK")  
public @interface LOCK {  
} 

 

 

@Produces    返回的MIME媒体类型,例如application/xml

 

 

@Consumes    可接受请求的MIME媒体类型,例如application/xml

 

 

 参数注入注解

@PathParam,  @QueryParam,  @HeaderParam, @CookieParam,  @MatrixParam, @FormParam   参数来自HTTP请求的不同位置

  Matrix Param是一个嵌入在URI字符串中的name:value对,修饰Path中的一个片段。例如http://example.cars.com/mercedes/e55;color=black/2006。MMatrix Parm对@Path表达式是透明的,这个例子中还是使用@Path("/e55/{year}")。但是可以用@MatrixParam 注解将MatrixParam的值注入到方法参数中。

例如@GET public String getInfo(@MatrixParam("color") String color){...}

 

 

后面的文章中将介绍JAX-RS标准的一个实现:Jersey。

参考文章:

  http://www.codedata.com.tw/java/java-restful-1-jersey-and-jax-rs/

    http://www.ruanyifeng.com/blog/2011/09/restful

  http://liugang594.iteye.com/category/218423

 

RESTful和JAX-RS

原文:http://www.cnblogs.com/pixy/p/4838268.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!