Java RESTful Web(JAX-RS)
2017-10-20 20:28
225 查看
Java 资源
JAX-RS 建立了一种特殊的语言来描述资源,正如由其编程模型所表示的。有五种主要条目:根资源、子资源、资源方法、子资源方法以及子资源定位器。
根资源是由
1 给出了一个例子。
清单 1. JAX-RS 根资源
子资源是作为 subresource locator 调用的结果返回的 Java
类。它们类似于根资源,只不过它们不是由
HTTP 请求方法指示符(designator)注释的方法以便服务此请求。如果它们不包含如此注释的方法,那么它们将会通过指派给合适的子资源定位器来进一步解析此资源处理请求。
清单 2. JAX-RS 子资源
如上所示的清单 2 展示了由
HTTP GET 请求被发送给
资源方法是根资源或子资源内绑定到 HTTP 方法的 Java 方法。绑定是通过诸如
清单 3. JAX-RS 资源方法
在清单 3 的例子中,发送到
子资源方法非常类似于资源方法;惟一的区别是子资源方法也是由
清单 4. JAX-RS 子资源方法
在清单 4 中,发送到
子资源定位器是能进一步解析用来处理给定请求的资源的一些方法。它们非常类似于子资源方法,因它们具备一个
HTTP 请求方法指示符,比如
清单 5. JAX-RS 子资源定位器
在上述例子中,对
URL 值。
本节将会探讨一些重要的注释及其使用。对于由 JAX-RS 规范提供的注释的完整列表,可以参考本文的 参考资料 部分给出的
JSR-311 链接。
6 的例子展示了
清单 6. @Path 的使用
URL 部分)都将由
@GET、@POST、@PUT、@DELETE 以及 @HEAD 均是 HTTP 请求方法指示符注释。您可以使用它们来绑定根资源或子资源内的 Java 方法与 HTTP 请求方法。HTTP GET 请求被映射到由 @GET 注释的方法;HTTP POST 请求被映射到由 @POST 注释的方法,以此类推。用户可能还需要通过使用
HTTP 请求方法指示符。
清单 7. 定制的 HTTP 请求方法指示符注释
上述的声明定义了
MIME 类型。这些注释均可在资源、资源方法、子资源方法、子资源定位器或子资源内找到。
清单 8. @Consumes/@Produces
对于上述的
HTTP 请求头。
在清单 9 中,
POST,表明我们的
清单 9. Content-Type 头部的使用
相反地,
清单 10. Accept 头部的使用
在清单 10 中,对 /contacts/johndoe@us.ibm.com 的
text/xml。
JAX-RS 提供程序是一些应用程序组件,允许在三个关键领域进行运行时行为的定制:数据绑定、异常映射以及上下文解析(比如,向运行时提供 JAXBContext 实例)。每个 JAX-RS 提供程序类必须由
MessageBodyWriters 被 JAX-RS 运行时用来序列化所返回资源的表示。遵从 JSR-311 的运行时提供了对常见类型(java.lang.String、java.io.InputStream、 JAXB 对象等)的本机支持,但用户也可以向 JAX-RS 运行时提供他或她自己的 MessageBodyWriter。比如,您可以提供一个定制
类型,如下所示。
清单 11. 定制 MessageBodyWriter
true 且
MessageBodyReaders 则与 MessageBodyWriters 相反。对于反序列化,JAX-RS 运行时支持与序列化相同的类型。用户也可以提供他或她自己的 MessageBodyReader 实现。MessageBodyReader 的最主要的功能是读取请求
Java 对象。
12。
清单 12. 定制 MessageBodyReader
与 MessageBodyWriter
MessageBodyReader 能否处理此输入。如果
至此,我们探讨了 JAX-RS 资源类和一些提供程序类(MessageBodyReaders 和 MessageBodyWriters)。那么,该如何在 JAX-RS 运行时内配置这些类呢?这可以通过扩展 javax.ws.rs.core.Application 类实现。此类提供了一组类或一组单例(singleton)对象实例,在一个 JAX-RS 应用程序内包括所有的 根级别的资源和提供程序(由
Application 类,它应该类似于清单 13。
清单 13. ContactInfoApplication
JAX-RS 提供程序视为单例是没有问题的,但将一个 JAX-RS 资源视为单例则要格外谨慎。常被 JAX-RS 资源类使用的基于注释的注入可能在一个单例实例的情况内并不受支持。因此,除非仔细计划,否则应该避免使用 JAX-RS 资源的单例实例。
假设,您正在一个 servlet 容器内部署一个 JAX-RS 应用程序,有两种方法可以向 JAX-RS 运行时注册您的 javax.ws.rs.core.Application 子类。这是由 WAR 文件的 web.xml 处理的,如下所示。
清单 14. 不能感知 JAX-RS 的 servlet 容器
在一个被认为是不能感知 JAX-RS 的 servlet 容器内,应该作为 servlet 定义内的 init-param 提供 Application 子类名。init-param 的名字必须是 javax.ws.rs.Application。servlet 类则很可能是 JAX-RS 运行时系统 servlet。您可以列出每个可能的 URL 模式,或者使用
清单 15. 能感知 JAX-RS 的 servlet 容器
在一个被认为是能感知 JAX-RS 的 servlet 容器内,必须作为 servlet 定义内的 servlet 类元素的值提供 Application 子类名。您仍然可以选择是列出每个可能的 URL 模式还是使用
下一步是找到一个能够支持 JAX-RS 内的可用功能的运行时。Apache Wink 项目就提供了一个能满足这种要求的运行时,具有上面所述的所有特性(参见 参考资料)。起初,Wink
是由开源社区的多个厂商和成员发起的一个协作项目。该项目的目的是提供最为灵活和轻量级的运行时。
除了标准 JAX-RS 特性之外,Wink 还提供了对 JSON、Atom 和 RSS 序列化格式的增强支持。JAX-RS 本身并不提供客户机 API,但 Wink 包括了其对客户机 API 的自身模型,并且是完全以资源为中心的。
在 My developerWorks 上加入 Apache Wink 组
在 My
developerWorks Apache Wink 组 中与其他开发人员进行有关如何开发 Apache Wink 的主题讨论和资源共享。
还不是 My developerWorks 的成员? 现在就加入!
为了简化基于 Wink 的服务的开发,可以下载 Wink 1.0 库并将它们作为默认 JAX-RS 库包括到 Rational Application Developer (RAD) 7.5.5 开发环境(参见 参考资料)中。在这个更新版本中,RAD
添加了一个 JAX-RS facet,可供您进行配置以支持验证器和注释帮助。这个新的 facet 还能通过自动生成所需的 servlet 项和映射来简化 servlet 的配置。
与传统的 servlet 模型相比,JAX-RS 提供了一种可行的、更为简便、移植性更好的方式来在 Java 内实现 RESTful 服务。使用注释让您能够轻松提供 Java 资源的路径位置并将 Java 方法绑定到 HTTP 请求方法。一种可移植的数据绑定架构提供了一些本机的 Java 类型支持并允许进行序列化/反序列化处理的完全定制。javax.ws.rs.core. Application 子类的扩展以及 web.xml 内的相应清单表明了用最少的部署描述符配置就能进行轻松部署。
本文只涉及了 JAX-RS 所能提供功能的一部分。就提供应用程序上下文(比如 JAXBContext 实例)并将运行时异常映射给 HTTP 请求而言,其他两个 JAX-RS 提供程序类型
必将是一种面向基于 Java 的 RESTful 服务开发的简便、可移植的、全面的 API。
来源:https://www.ibm.com/developerworks/cn/web/wa-jaxrs/
JAX-RS 建立了一种特殊的语言来描述资源,正如由其编程模型所表示的。有五种主要条目:根资源、子资源、资源方法、子资源方法以及子资源定位器。
根资源
根资源是由 @Path注释的 Java 类。
@Path注释提供了一个
value属性,用来表明此资源所在的路径。
value属性可以是文本字符、变量或变量外加一个定制的正则表达式。清单
1 给出了一个例子。
清单 1. JAX-RS 根资源
子资源
子资源是作为 subresource locator 调用的结果返回的 Java类。它们类似于根资源,只不过它们不是由
@Path注释的,因它们的路径是由子资源定位器给出的。子资源通常包含由
HTTP 请求方法指示符(designator)注释的方法以便服务此请求。如果它们不包含如此注释的方法,那么它们将会通过指派给合适的子资源定位器来进一步解析此资源处理请求。
清单 2. JAX-RS 子资源
ContactsResource.getContactDepartment方法返回的子资源。在这个例子中,如果一个
HTTP GET 请求被发送给
/contact/{contactName}/department路径,那么
Department子资源内的
getDepartmentName资源方法就会处理此请求。
资源方法
资源方法是根资源或子资源内绑定到 HTTP 方法的 Java 方法。绑定是通过诸如 @GET这样的注释完成的。
清单 3. JAX-RS 资源方法
/contacts路径的 HTTP GET 请求将会由
getContacts()资源方法处理。
子资源方法
子资源方法非常类似于资源方法;惟一的区别是子资源方法也是由 @Path注释的,此注释进一步限定了该方法的选择。
清单 4. JAX-RS 子资源方法
/contacts/ids路径的 HTTP GET 请求将会由
getContactIds()子资源方法处理。
子资源定位器
子资源定位器是能进一步解析用来处理给定请求的资源的一些方法。它们非常类似于子资源方法,因它们具备一个 @Path注释,但不具备
HTTP 请求方法指示符,比如
@GET注释。
清单 5. JAX-RS 子资源定位器
/contact/{contactName}/department路径的任何 HTTP 请求都将由
getContactDepartment子资源定位器处理。
{contactName}部分表明
contact路径部分之后可以是任何合法的
URL 值。
注释
本节将会探讨一些重要的注释及其使用。对于由 JAX-RS 规范提供的注释的完整列表,可以参考本文的 参考资料 部分给出的JSR-311 链接。
@Path
@Path注释被用来描述根资源、子资源方法或子资源的位置。
value值可以包含文本字符、变量或具有定制正则表达式的变量。清单
6 的例子展示了
@Path注释的主要应用。
清单 6. @Path 的使用
ContactsResource类上的注释表明对
/contacts路径的所有请求都将由
ContactsResource根资源处理。
getByEmailAddress上的
@Path注释则表明任何发送到
/contacts/{emailAddress}的请求(其中
emailAddress代表的是正则表达式
.+@.+\\.[a-z]+)都将由
getByEmailAddress处理。
getByLastName方法上的
@Path注释指定了发送到
/contacts/{lastName}路径的所有请求(其中
lastName代表的是一个与
getByEmailAddress内的正则表达式不匹配的有效的
URL 部分)都将由
getByLastName方法处理。
@GET、@POST、@PUT、@DELETE、@HEAD
@GET、@POST、@PUT、@DELETE 以及 @HEAD 均是 HTTP 请求方法指示符注释。您可以使用它们来绑定根资源或子资源内的 Java 方法与 HTTP 请求方法。HTTP GET 请求被映射到由 @GET 注释的方法;HTTP POST 请求被映射到由 @POST 注释的方法,以此类推。用户可能还需要通过使用 @HttpMethod注释定义其自己的定制
HTTP 请求方法指示符。
清单 7. 定制的 HTTP 请求方法指示符注释
@CustomGET注释。此注释将具有与 @GET 注释相同的语义值并可用在其位置上。
@Conumes 和 @Produces
@Consumes注释代表的是一个资源可以接受的 MIME 类型。
@Produces注释代表的是一个资源可以返回的
MIME 类型。这些注释均可在资源、资源方法、子资源方法、子资源定位器或子资源内找到。
清单 8. @Consumes/@Produces
getByEmailAddress和
addContactInfo方法,它们均能处理
text/xml和
application/json。被接受或返回的资源表示将依赖于客户机设置的
HTTP 请求头。
@Consumes注释针对
Content-Type请求头进行匹配,以决定方法是否能接受给定请求的内容。
在清单 9 中,
application/json的
Content-Type头再加上对路径
/contacts的
POST,表明我们的
ContactsResource类内的
addContactInfo方法将会被调用以处理请求。
清单 9. Content-Type 头部的使用
@Produces注释被针对
Accept请求头进行匹配以决定客户机是否能够处理由给定方法返回的表示。
清单 10. Accept 头部的使用
GET请求表明了
getByEmailAddress方法将会被调用并且返回的格式将会是
application/json,而非
text/xml。
Providers
JAX-RS 提供程序是一些应用程序组件,允许在三个关键领域进行运行时行为的定制:数据绑定、异常映射以及上下文解析(比如,向运行时提供 JAXBContext 实例)。每个 JAX-RS 提供程序类必须由 @Provider注释。如下的例子讨论了两个数据绑定提供程序
MessageBodyWriter和
MessageBodyReader。
MessageBodyWriter
MessageBodyWriters 被 JAX-RS 运行时用来序列化所返回资源的表示。遵从 JSR-311 的运行时提供了对常见类型(java.lang.String、java.io.InputStream、 JAXB 对象等)的本机支持,但用户也可以向 JAX-RS 运行时提供他或她自己的 MessageBodyWriter。比如,您可以提供一个定制 MessageBodyWriter来处理定制
ContactInfoJava
类型,如下所示。
清单 11. 定制 MessageBodyWriter
ContactInfoWriter则在所返回的资源表示被序列化之前由 JAX-RS 运行时调用。如果
isWriteable返回
true 且
@Produces是此资源方法的
@Produces值最为接近的匹配,就会调用
writeTo方法。在这里,
ContactInfoWriter负责向底层的
OutputStream序列化
ContactInfo实例的内容。
MessageBodyReader
MessageBodyReaders 则与 MessageBodyWriters 相反。对于反序列化,JAX-RS 运行时支持与序列化相同的类型。用户也可以提供他或她自己的 MessageBodyReader 实现。MessageBodyReader 的最主要的功能是读取请求 InputStream并将传入的字节反序列化到一个此资源方法期望的
Java 对象。
ContactInfo类型的
MessageBodyReader可以类似于清单
12。
清单 12. 定制 MessageBodyReader
isWriteable类似,
ContactInfoReader的
isReadable方法将被调用以便决定
MessageBodyReader 能否处理此输入。如果
isReadable返回 true 且
@Consumes值与此资源方法的
@Consumes值最为匹配,就会选择
ContactInfoReader。当
readFrom方法被调用时,结果会是基于请求
InputStream的内容创建
ContactInfo实例。
配置
至此,我们探讨了 JAX-RS 资源类和一些提供程序类(MessageBodyReaders 和 MessageBodyWriters)。那么,该如何在 JAX-RS 运行时内配置这些类呢?这可以通过扩展 javax.ws.rs.core.Application 类实现。此类提供了一组类或一组单例(singleton)对象实例,在一个 JAX-RS 应用程序内包括所有的 根级别的资源和提供程序(由 @Provider注释的类)。若为这个示例联系信息应用程序扩展这个
Application 类,它应该类似于清单 13。
清单 13. ContactInfoApplication
getClasses方法为 JAX-RS 运行时提供了一组可用于元数据的类。请注意,
getSingletons方法什么都不返回。通常而言,将
JAX-RS 提供程序视为单例是没有问题的,但将一个 JAX-RS 资源视为单例则要格外谨慎。常被 JAX-RS 资源类使用的基于注释的注入可能在一个单例实例的情况内并不受支持。因此,除非仔细计划,否则应该避免使用 JAX-RS 资源的单例实例。
假设,您正在一个 servlet 容器内部署一个 JAX-RS 应用程序,有两种方法可以向 JAX-RS 运行时注册您的 javax.ws.rs.core.Application 子类。这是由 WAR 文件的 web.xml 处理的,如下所示。
清单 14. 不能感知 JAX-RS 的 servlet 容器
/*通配符注册,如下所示。
清单 15. 能感知 JAX-RS 的 servlet 容器
/*通配符注册。
以 Apache Wink 作为运行时的 JAX-RS
下一步是找到一个能够支持 JAX-RS 内的可用功能的运行时。Apache Wink 项目就提供了一个能满足这种要求的运行时,具有上面所述的所有特性(参见 参考资料)。起初,Wink是由开源社区的多个厂商和成员发起的一个协作项目。该项目的目的是提供最为灵活和轻量级的运行时。
除了标准 JAX-RS 特性之外,Wink 还提供了对 JSON、Atom 和 RSS 序列化格式的增强支持。JAX-RS 本身并不提供客户机 API,但 Wink 包括了其对客户机 API 的自身模型,并且是完全以资源为中心的。
在 My developerWorks 上加入 Apache Wink 组
在 My
developerWorks Apache Wink 组 中与其他开发人员进行有关如何开发 Apache Wink 的主题讨论和资源共享。
还不是 My developerWorks 的成员? 现在就加入!
为了简化基于 Wink 的服务的开发,可以下载 Wink 1.0 库并将它们作为默认 JAX-RS 库包括到 Rational Application Developer (RAD) 7.5.5 开发环境(参见 参考资料)中。在这个更新版本中,RAD
添加了一个 JAX-RS facet,可供您进行配置以支持验证器和注释帮助。这个新的 facet 还能通过自动生成所需的 servlet 项和映射来简化 servlet 的配置。
结束语
与传统的 servlet 模型相比,JAX-RS 提供了一种可行的、更为简便、移植性更好的方式来在 Java 内实现 RESTful 服务。使用注释让您能够轻松提供 Java 资源的路径位置并将 Java 方法绑定到 HTTP 请求方法。一种可移植的数据绑定架构提供了一些本机的 Java 类型支持并允许进行序列化/反序列化处理的完全定制。javax.ws.rs.core. Application 子类的扩展以及 web.xml 内的相应清单表明了用最少的部署描述符配置就能进行轻松部署。本文只涉及了 JAX-RS 所能提供功能的一部分。就提供应用程序上下文(比如 JAXBContext 实例)并将运行时异常映射给 HTTP 请求而言,其他两个 JAX-RS 提供程序类型
ContextResolvers和
ExceptionMappingProviders还能提供对应用程序组件的进一步控制。注释的定义是为了控制方法参数和类成员的注入,它们在运行时的整个过程向应用程序提供了有价值的上下文信息。总的来说,JAX-RS
必将是一种面向基于 Java 的 RESTful 服务开发的简便、可移植的、全面的 API。
来源:https://www.ibm.com/developerworks/cn/web/wa-jaxrs/
相关文章推荐
- jax-rs(Java API for RESTful Web Services) 实践教程 之五 —— 注入全局变量 和 rest的生命周期
- jboss7 Java API for RESTful Web Services (JAX-RS) 官方文档
- 用 Java 技术创建 RESTful Web (服务 JAX-RS:一种更为简单、可移植性更好的替代方式)
- JAX-RS介绍——Java API forRESTful WebServices,JAX-RS的目标是Web Services开发(这与HTML Web应用不同)而Spring MVC的目标则是Web应用开发
- JAX-RS(Java API for RESTful Web Service)_1.1解析
- jax-rs(Java API for RESTful Web Services)实践教程 之二 —— get/post/put/delete/head
- jax-rs(Java API for RESTful Web Services) 实践教程 之三 —— 生产Produces与消费Consumes
- JAX-RS -- Java API for RESTful Web Services
- jax-rs(Java API for RESTful Web Services) 实践教程 之一 —— 初探jax-rs
- jax-rs(Java API for RESTful Web Services)实践教程 之二 —— get/post/put/delete/head
- jax-rs(Java API for RESTful Web Services) 实践教程 之四 —— @Context注入HttpServletRequest 使REST保持状态!
- RESTful Web 服务 - Java (JAX-RS)
- RESTful Webservices with Java (Jersey / JAX-RS)
- JAX-RS(Java API for RESTful Web Services)常用注解
- Java Web Service相关的若干概念(JAX-WS,JAX-RS)
- Java JAX-WS和JAX-RS webservice的区别和特点
- Java JAX-WS和JAX-RS webservice
- 使用JAX-RS创建RESTful Web Service
- 与Java Web Service相关的若干概念(JAX-WS,JAX-RS)
- java 利用JAX-RS快速开发RESTful 服务