第 51 章 实体支持
摘要
Apache CXF 运行时支持开箱即用 MIME 类型和 Java 对象之间的有限映射。开发人员可以通过实施自定义读取器和写入器来扩展映射。自定义读取器和写入器在启动时使用运行时注册。
概述 复制链接链接已复制到粘贴板!
该运行时依赖于 JAX-RS MessageBodyReader 和 MessageBodyWriter 实现,以在 HTTP 消息及其 Java 表示之间序列化和反序列化数据。读取器和写入器可以限制其能够处理的 MIME 类型。
运行时为多个常用映射提供读取器和写入器。如果应用程序需要更高级的映射,开发人员可以提供消息BodyReader 接口和/或 MessageBodyWriter 接口的自定义实现。在应用程序启动时,自定义读取器和写入器会在运行时注册。
原生支持的类型 复制链接链接已复制到粘贴板!
表 51.1 “原生支持的实体映射” 列出 Apache CXF 提供的实体映射。
| Java 类型 | MIME 类型 |
|---|---|
| 原语类型 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| JAXB 注解的对象 |
|
| javax.ws.rs.core.MultivaluedMap<String, String> |
|
| javax.ws.rs.core.StreamingOutput |
|
[a]
此映射用于处理 HTML 表单数据。
[b]
此映射只支持将数据返回到消费者。
| |
自定义读取器 复制链接链接已复制到粘贴板!
自定义实体读取器负责将传入的 HTTP 请求映射到服务实施可以操作的 Java 类型。它们实施 javax.ws.rs.ext.MessageBodyReader 接口。
接口在 例 51.1 “消息读取器界面” 中显示,有两个需要实现的方法:
例 51.1. 消息读取器界面
isReadable()isReadable()方法决定了读者是否能够读取数据流并创建正确类型的实体表示。如果读取器可以创建正确类型的实体,则方法返回为true。表 51.2 “用于确定读取器是否可生成实体的参数” 描述
isReadable()方法的参数。Expand 表 51.2. 用于确定读取器是否可生成实体的参数 参数 类型 描述 typeclass<T>指定用于存储实体的对象的实际 Java 类。
genericType类型
指定用于存储实体的对象的 Java 类型。例如,如果消息正文被转换为方法参数,则该值将是
Method.getGenericParameterTypes()方法返回的方法参数类型。annotationsannotation[]
指定用于存储该实体创建的对象的声明上的注解列表。例如,如果消息正文被转换为方法参数,这将是
Method.getParameterAnnotations()方法返回的注解。mediaTypeMediatType指定 HTTP 实体的 MIME 类型。
readFrom()readFrom()方法读取 HTTP 实体,并将其涉及所需的 Java 对象。如果读取成功,则方法返回包含该实体的创建的 Java 对象。如果在读取输入流时发生错误,方法应该会抛出 IOException 异常。如果发生需要 HTTP 错误响应的错误,应当抛出带 HTTP 响应的 WebApplicationException。表 51.3 “用于读取实体的参数” 描述
readFrom()方法的参数。Expand 表 51.3. 用于读取实体的参数 参数 类型 描述 typeclass<T>指定用于存储实体的对象的实际 Java 类。
genericType类型
指定用于存储实体的对象的 Java 类型。例如,如果消息正文被转换为方法参数,则该值将是
Method.getGenericParameterTypes()方法返回的方法参数类型。annotationsannotation[]
指定用于存储该实体创建的对象的声明上的注解列表。例如,如果消息正文被转换为方法参数,这将是
Method.getParameterAnnotations()方法返回的注解。mediaTypeMediatType指定 HTTP 实体的 MIME 类型。
httpHeadersMultivaluedMap<String, String>
指定与实体关联的 HTTP 消息标头。
entityStreamInputStream指定包含 HTTP 实体的输入流。
重要这个方法不应该关闭输入流。
在将 MessageBodyReader 实施用作实体读取器之前,必须先将它与 javax.ws.rs.ext.Provider 注解进行解码。@Provider 注释提醒提供额外功能的运行时。这种实现还必须与运行时注册,如 “注册读者和写器”一节 所述。
默认情况下,自定义实体提供商处理所有 MIME 类型。您可以使用 javax.ws.rs.Consumes 注解限制自定义实体读取器处理的 MIME 类型。@Consumes 注释指定自定义实体提供程序所读取的以逗号分隔的 MIME 类型列表。如果实体不是指定的 MIME 类型,则实体提供商不会选择为可能的 reader。
例 51.2 “XML 源实体读取器” 显示实体读取者消耗 XML 实体并将其存储在 Source 对象中。
例 51.2. XML 源实体读取器
自定义写入器 复制链接链接已复制到粘贴板!
自定义实体作者负责将 Java 类型映射到 HTTP 实体。它们实施 javax.ws.rs.ext.MessageBodyWriter 接口。
接口在 例 51.3 “消息写入程序接口” 中显示,有三个需要实现的方法:
例 51.3. 消息写入程序接口
isWriteable()isWriteable()方法决定了实体作者是否可以将 Java 类型映射到正确的实体类型。如果写入器可以进行映射,方法会返回true。表 51.4 “用于读取实体的参数” 描述
isWritable()方法的参数。Expand 表 51.4. 用于读取实体的参数 参数 类型 描述 typeclass<T>指定正在写入对象的 Java 类。
genericType类型
通过反映资源方法返回类型或通过返回的实例检查,指定要写入的 Java 类型。
GenericEntity类(在 第 48.4 节 “使用通用类型信息返回实体” 所述)提供了对控制这个值的支持。annotationsannotation[]
指定返回实体的方法上的注解列表。
mediaTypeMediatType指定 HTTP 实体的 MIME 类型。
getSize()getSize()方法在writeTo()之前调用。它返回所写入实体的长度,以字节为单位。如果返回正值,则该值将写入到 HTTP 消息的Content-Length标头中。表 51.5 “用于读取实体的参数” 描述
getSize()方法的参数。Expand 表 51.5. 用于读取实体的参数 参数 类型 描述 tgeneric
指定正在写入的实例。
typeclass<T>指定正在写入对象的 Java 类。
genericType类型
通过反映资源方法返回类型或通过返回的实例检查,指定要写入的 Java 类型。
GenericEntity类(在 第 48.4 节 “使用通用类型信息返回实体” 所述)提供了对控制这个值的支持。annotationsannotation[]
指定返回实体的方法上的注解列表。
mediaTypeMediatType指定 HTTP 实体的 MIME 类型。
writeTo()writeTo()方法将 Java 对象转换为所需的实体类型,并将实体写入到输出流。如果在将实体写入输出流时发生错误,则方法应抛出 IOException 异常。如果发生需要 HTTP 错误响应的错误,应当抛出带 HTTP 响应的 WebApplicationException。表 51.6 “用于读取实体的参数” 描述
writeTo()方法的参数。Expand 表 51.6. 用于读取实体的参数 参数 类型 描述 tgeneric
指定正在写入的实例。
typeclass<T>指定正在写入对象的 Java 类。
genericType类型
通过反映资源方法返回类型或通过返回的实例检查,指定要写入的 Java 类型。
GenericEntity类(在 第 48.4 节 “使用通用类型信息返回实体” 所述)提供了对控制这个值的支持。annotationsannotation[]
指定返回实体的方法上的注解列表。
mediaTypeMediatType指定 HTTP 实体的 MIME 类型。
httpHeadersMultivaluedMap<String, Object>
指定与实体关联的 HTTP 响应标头。
entityStreamOutputStream指定将实体写入的输出流。
在消息BodyWriter 实施可用作实体写器之前,它必须通过 javax.ws.rs.ext.Provider 注释来解码。@Provider 注释提醒提供额外功能的运行时。这种实现还必须与运行时注册,如 “注册读者和写器”一节 所述。
默认情况下,自定义实体提供商处理所有 MIME 类型。您可以使用 javax.ws.rs.Produces 注释限制自定义实体写入器的 MIME 类型。@Produces 注释指定自定义实体提供程序生成的以逗号分隔的 MIME 类型列表。如果实体不是指定的 MIME 类型,则实体提供商不会选择作为可能的写入器。
例 51.4 “XML 源实体作者” 显示取源对象并生成 XML 实体的实体作者。
例 51.4. XML 源实体作者
注册读者和写器 复制链接链接已复制到粘贴板!
在 JAX-RS 应用可以使用任何自定义实体提供程序之前,必须将自定义提供程序注册到运行时。提供程序使用应用配置文件中的 jaxrs:providers 元素或使用 JAXRSServeronnectionFactoryyBean 类通过运行时注册。
jaxrs:providers 元素是 jaxrs:server 元素的子级,含有 bean 元素的列表。每个 bean 元素定义一个实体提供程序。
例 51.5 “使用运行时注册实体供应商” 显示配置为使用一组自定义实体提供程序的 JAX-RS 服务器。
例 51.5. 使用运行时注册实体供应商
JAXRSServerFactoryBean 类是 Apache CXF 扩展,提供对配置 API 的访问。它有一个 setProvider() 方法,用于将实例化的实体提供程序添加到应用程序中。例 51.6 “以编程方式注册实体供应商” 显示以编程方式注册实体提供程序的代码。
例 51.6. 以编程方式注册实体供应商