1.3 解读JAX-RS标准
JAX-RS是Java领域的REST式的Web服务的标准规范,是使用Java完成REST服务的基本约定。
1.3.1 JAX-RS2标准
Java领域中的Web Service是指实现SOAP协议的JAX-WS。直到Java EE 6(发布于2008年9月)通过JCP(Java Community Process)组织定义的JSR311(http://www.jcp.org/en/jsr/detail?id=311),才将REST在Java领域标准化。
JSR311名为The Java API for RESTful Web Service,即JAX-RS,其参考实现是Glassfish项目中的Jersey1.0。此后,JSR311进行了一次升级(2009年9月),即JAXRS1.1。JAX-RS诞生后,时隔5年(2013年5月)发布的Java EE7包含了JSR339,将JAXRS升级到JAX-RS2(http://www.jcp.org/en/jsr/detail?id=339)。JAX-RS2.0在前面版本的基础上增加了很多实用性的功能,比如对REST客户端API的定义,异步REST等,对REST的支持更加完善和强大。
JAX-RS的版本对应的参考实现Jersey项目版本信息参见表1-1。
表1-1 JAX-RS标准和Jersey版本信息
1.3.2 JAX-RS2的目标
JAX-RS2标准(即JSR339)中定义了目标、非目标和元素等内容。JSR339标准中的这部分内容通常被以实现业务功能为目的的开发人员所忽视,在此和读者分享的一个开发经验是:要掌握一项技术,先要掌握它背后标准的定义。首先我们来看看JAX-RS2的目标。
1)基于POJO:JAX-RS2的API提供一组注解(annotation)和相关的接口、类,并定义了POJO(Plain Ordinary Java Object)对象的生命周期和作用域。规定使用POJO来公布Web资源。
2)以HTTP为中心:JAX-RS2采用HTTP协议,并提供清晰的HTTP和统一资源定位(URI)元素来映射相关的API类和注解。JAX-RS2的API不但支持通用的HTTP使用模式,还对WebDAV和Atom等扩展协议提供灵活的支持。
3)格式独立性:JAX-RS2对传输数据(HTTP Entity)的类型/格式的支持非常宽泛,允许在标准风格之上使用额外的数据类型。
4)容器独立性:JAX-RS2的应用可以部署在各种Servlet容器中,比如Tomcat/Jetty,也可以部署在支持JAX-WS的容器中,比如GlassFish。
5)内置于Java EE:JAX-RS2是Java EE规范的一部分,它定义了在一个Java EE容器内的Web资源类的内部,如何使用Java EE的功能和组件。
阅读指南
WebDAV(Web-based Distributed Authoring and Versioning,基于Web的分布式创作和版本控制)是IETF组织的RFC2518协议。WebDAV基于并扩展了HTTP 1.1,在HTTP标准方法以外添加了以下内容。
❏Mkcol:创建集合。
❏PropFind/PropPatch:针对资源和集合检索和设置属性。
❏Copy/Move:管理命名空间上下文中的集合和资源。
❏Lock/Unlock:改写保护,支持文件的版本控制。
针对在REST风格的Web服务中是否应该使用WebDAV,业内的声音并不一致,持反对意见的主要观点是WebDAV带来了非统一的接口,这违背了REST的初衷。本书的示例将不采用WebDAV,但文字部分将讲述如何支持WebDAV。Atom类型传输格式将在2.3节讲述。
1.3.3 非JAX-RS2的目标
那么哪些不是JAX-RS2的目标呢?
1)对J2SE 6.0之前版本的支持:JAX-RS2中大量使用了注解(annotation),需要J2SE 6.0以及更新的版本,因此不提供对J2SE 6.0以下版本的支持。
2)对服务的描述、注册和探测:JAX-RS2没有定义也无须支持任何服务的描述(description)、服务的注册(registration)和服务的探测(discovery)。
3)HTTP协议栈:JAX-RS2没有定义新的HTTP协议栈。承载JAX-RS2应用的容器提供对HTTP协议的支持。
4)数据类型/格式类:JAX-RS2没有定义处理实体内容的类,它将这一类型的类交由使用JAX-RS2的应用中的类去实现。
1.3.4 解读JAX-RS元素
最后,我们来看看JAX-RS2中定义了哪些元素。
1)资源类:使用JAX-RS注解来实现相关Web资源的Java类。如果用MVC的三层结构来解读,那么资源类位于最前端,用于接收请求和返回响应。通常,但不是约定,我们使用resource作为包名,三层的包定义形如:resource-service-dao。
2)根资源类:使用@Path注解,提供资源类树的根资源及其子资源的访问。资源类分为根资源类和子资源类,由于Jersey默认提供WADL(参见1.6节),每个应用公布的全部资源接口可以通过WADL页面查阅。
3)请求方法标识符:使用运行期注解@HttpMethod,用来标识处理资源的HTTP请求方法。该方法将使用资源类的相应方法处理,标准的方法包括DELETE、GET、HEAD、OPTIONS、POST、PUT,详见2.1节。
4)资源方法:资源类中定义的方法使用了请求方法标识符,用来处理相关资源的请求。就是上面提到的资源类的相应方法。
5)子资源标识符:资源类中定义的方法,用来定位相关资源的子资源。
6)子资源方法:资源类中定义的方法,用来处理相关资源的子资源的请求。
7)Provider:一种JAX-RS扩展接口的实现类,扩展了JAX-RS运行期的能力。第4章详述了各种Provider及其实现。
8)Filter:一种用于过滤请求和响应的Provider,详见3.3节。
9)Entity Interceptor:一种用于处理拦截消息读写的Provider,详见3.5节。
10)Invocation:一种用于配置发布HTTP请求的客户端API对象,详见5.1.3节。
11)WebTarget:一种使用URI标识的Invocation容器对象,详见5.1.2节。
12)Link:一种携带元数据的URI,包括媒体类型、关系和标题等,详见2.4节。