18.3. 使用模型架构定义 REST 服务
没有注解的 RESTful 服务
借助 JAX-RS 模型模式,可以在不 注解 Java 类的情况下定义 RESTful 服务。也就是说,不使用 @Path
、@PathParam
、@Consumes
、@Consumes、@Produces
等等,直接发送到 Java 类(或接口),您可以提供单独的 XML 文件中的所有相关 REST 元数据。例如,在无法修改实现该服务的 Java 源时,这很有用。
模型 schema 示例
例 18.1 “JAX-RS 模型架构示例” 显示了一个模型架构示例,它定义了 BookStoreNoAnnotations
root 资源类的服务元数据。
例 18.1. JAX-RS 模型架构示例
<model xmlns="http://cxf.apache.org/jaxrs"> <resource name="org.apache.cxf.systest.jaxrs.BookStoreNoAnnotations" path="bookstore" produces="application/json" consumes="application/json"> <operation name="getBook" verb="GET" path="/books/{id}" produces="application/xml"> <param name="id" type="PATH"/> </operation> <operation name="getBookChapter" path="/books/{id}/chapter"> <param name="id" type="PATH"/> </operation> <operation name="updateBook" verb="PUT"> <param name="book" type="REQUEST_BODY"/> </operation> </resource> <resource name="org.apache.cxf.systest.jaxrs.ChapterNoAnnotations"> <operation name="getItself" verb="GET"/> <operation name="updateChapter" verb="PUT" consumes="application/xml"> <param name="content" type="REQUEST_BODY"/> </operation> </resource> </model>
命名空间
用于定义模型模式的 XML 命名空间取决于您在 Blueprint XML 中定义对应的 JAX-RS 端点还是在 Spring XML 中定义。下表显示了用于 XML 语言的命名空间:
XML 语言 | 命名空间 |
---|---|
蓝图(Blueprint) | |
Spring |
如何将模型模式附加到端点
要在端点上定义和附加模型模式,请执行以下步骤:
- 使用您选择的注入平台(Blueprint XML 或 Spring XML)的适当 XML 命名空间定义模型架构。
将模型模式文件添加到您的项目的资源,以便架构文件可在最终软件包(JAR、WAR 或 OSGi 捆绑包文件)上提供。
注意另外,还可以使用端点的
jaxrs:model
子元素将模型模式直接嵌入到 JAX-RS 端点中。-
将端点配置为使用模型模式,方法是将端点的
modelRef
属性设置为 classpath 上模型架构的位置(使用 classpath URL)。 -
如有必要,使用
jaxrs:serviceBeans
元素明确实例化根资源。如果模型模式直接引用根资源类(而不是引用基本接口),您可以跳过这一步。
引用类的模型架构配置
如果模型架构直接应用到根资源类,则不需要使用 jaxrs:serviceBeans
元素定义任何根资源anan,因为模型架构会自动实例化根资源 Bean。
例如,如果 customer-resources.xml
是一个模型的 schema,它将元数据与客户资源类相关联,您可以按照如下所示
实例化客户服务端点:
<jaxrs:server id="customerService" address="/customers" modelRef="classpath:/org/example/schemas/customer-resources.xml" />
配置模型架构引用接口
如果模型架构适用于 Java 接口(它是根资源的基本接口),则必须使用端点中的 jaxrs:serviceBeans
元素实例化根资源类。
例如,如果 customer-interfaces.xml
是一个模型 schema,它将元数据与客户接口相关联,您可以按照如下所示
实例化客户服务端点:
<jaxrs:server id="customerService" address="/customers" modelRef="classpath:/org/example/schemas/customer-interfaces.xml"> <jaxrs:serviceBeans> <ref component-id="serviceBean" /> </jaxrs:serviceBeans> </jaxrs:server> <bean id="serviceBean" class="service.CustomerService"/>
模型架构参考
模型模式使用以下 XML 元素定义:
model
-
模型架构的根元素。如果您需要引用模型模式(例如,使用
modelRef
属性的 JAX-RS 端点中),您应当设置此元素上的id
属性。 model/resource
资源
元素用于将元数据与特定的根资源类(或对应的接口)关联。您可以在resource
元素上定义以下属性:属性 描述 + name
将这个资源模型应用到的资源类(或对应接口)的名称。
+
path
映射到此资源的 REST URL 路径的组件。
+
使用
指定此资源使用的内容类型(Internet 介质类型),如
application/xml
或application/json
。+
produces
指定此资源生成的内容类型(互联网介质类型),如
application/xml
或application/json
。+
model/resource/operation
operation
元素用于将元数据与 Java 方法关联。您可以在operation
元素上定义以下属性:属性 描述 + name
此元素应用到的 Java 方法的名称。
+
path
映射到此方法的 REST URL 路径的组件。此属性值可以包括参数引用,例如:
path="/books/{id}/ preceding"
,其中{id}
会从路径中提取id
参数的值。+
verb
指定映射到此方法的 HTTP 动词。通常, :
GET
、POST
、PUT
或DELETE
.如果没有指定 HTTP 动词,则假设 Java 方法是一个 子资源定位器,它会返回一个对子资源对象的引用(其中子资源类还必须使用资源元素提供元数据
)。+
使用
指定此操作使用的内容类型(Internet 介质类型),如
application/xml
或application/json
。+
produces
指定此操作生成的内容类型(互联网介质类型),如
application/xml
或application/json
。+
Oneway
如果为
true
,将操作配置为 单向,即不需要回复信息。默认值为false
。+
model/resource/operation/param
param
元素用于从 REST URL 中提取值,并将其注入到其中一个方法参数中。您可以在param
元素上定义以下属性:属性 描述 + name
此元素应用到的 Java 方法参数的名称。
+
type
指定从 REST URL 或消息中提取参数值的方式。可以将其设置为以下值之一:
PATH
、QUERY
、MATRIX
、HEAHER、COOKIE
、FORM
、CONTEXT
、REQUEST_BODY
。+
defaultValue
要注入到参数的默认值,因为无法从 REST URL 或消息中提取值。
+
编码
如果为
true
,则参数值以其 URI 编码形式注入(即,使用%n
编码代码)。默认为false
。例如,当从 URL 路径中提取参数时,/name/Joe%20Bloggs
将被编码设为true
,该参数会作为Joe%20Bloggs
注入到;否则,参数将作为Joe Bloggs
注入。+