4.3. Marshalling to and from Java Objects


Marshalling Java 对象用于通过 HTTP 传输

使用 REST 协议的最常见方法是传输消息正文中 Java bean 的内容。为了实现此目的,您需要有一个机制来划分 Java 对象到合适的数据格式。REST DSL 支持以下数据格式,适用于编码 Java 对象:

JSON

JSON (JavaScript 对象表示法)是一种轻量级数据格式,可轻松映射到 Java 对象或从 Java 对象进行映射。JSON 语法是紧凑、易于输入的,方便人类读取和写入。因此,JSON 被视为 REST 服务的消息格式。

例如,以下 JSON 代码可以代表一个 User bean,它有两个属性字段 idname

{
    "id" : 1234,
    "name" : "Jane Doe"
}
JAXB

JAXB (用于 XML 绑定的 Java 架构)是一种基于 XML 的数据格式,可以轻松地映射到 Java 对象或从 Java 对象进行映射。要将 XML 放入 Java 对象,您还必须注解要使用的 Java 类。

例如,以下 JAXB 代码可以代表一个 User bean,它有两个属性字段 idname

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<User>
  <Id>1234</Id>
  <Name>Jane Doe</Name>
</User>
注意

从 Camel 2.17.0 开始,JAXB 数据格式和类型转换器支持从 XML 转换到 POJO (使用 ObjectFactory 而不是 XmlRootElement )。另外,camel 上下文应包含值为 true 的 CamelJaxbObjectFactory 属性。但是,由于优化,默认值为 false。

JSON 和 JAXB 与 REST DSL 集成

当然,您可以编写所需的代码,以自行将消息正文转换为 Java 对象或从 Java 对象转换。但是 REST DSL 提供了自动执行此转换的方便。特别是,JSON 和 JAXB 与 REST DSL 集成具有以下优点:

  • Marshalling to 和 from Java 对象会自动执行(给定配置)。
  • REST DSL 可以自动检测数据格式(JSON 或 JAXB),并执行适当的转换。
  • REST DSL 提供了一个抽象层,因此您编写的代码不特定于特定的 JSON 或 JAXB 实施。因此,您可以稍后切换实施,且对应用程序代码的影响最小。

支持的数据格式组件

Apache Camel 提供了很多不同的 JSON 和 JAXB 数据格式实现。REST DSL 目前支持以下数据格式:

  • JSON

    • Jackson 数据格式(camel-jackson) (默认)
    • Gson 数据格式(camel-gson)
    • xstream 数据格式(camel-xstream)
  • JAXB

    • JAXB 数据格式(camel-jaxb)

如何启用对象划分

要在 REST DSL 中启用对象 marshalling,请观察以下点:

  1. 启用绑定模式,通过设置 bindingMode 选项(它是多个级别,您可以在其中设置绑定模式来设定详情,请参阅 “配置绑定模式”一节)。
  2. 在传入消息中使用 type 选项(必需),以及在传出消息中使用 outType 选项(可选)指定要转换为的 Java 类型。
  3. 如果要将 Java 对象转换为 JAXB 数据格式或从 JAXB 数据格式转换,您必须记得使用适当的 JAXB 注释来注释 Java 类。
  4. 使用 jsonDataFormat 选项和/或 xmlDataFormat 选项(可在 restConfiguration 构建器中指定),指定底层数据格式实现(或实现实现)。
  5. 如果您的路由以 JAXB 格式提供返回值,您通常预期将交换正文的 Out 消息设置为具有 JAXB 注释的类实例(一个 JAXB 元素)。如果您希望以 XML 格式直接提供 JAXB 返回值,但是,请使用键 xml.out.mustBeJAXBElement 设置 dataFormatProperty,使其为 false (可在 restConfiguration 构建器中指定)。例如,在 XML DSL 语法中:

    <restConfiguration ...>
      <dataFormatProperty key="xml.out.mustBeJAXBElement"
                          value="false"/>
      ...
    </restConfiguration>
  6. 将所需的依赖项添加到项目构建文件中。例如,如果您使用 Maven 构建系统,并且您使用 Jackson 数据格式,您可以在 Maven POM 文件中添加以下依赖项:

    <?xml version="1.0" encoding="UTF-8"?>
    <project ...>
      ...
      <dependencies>
        ...
        <!-- use for json binding --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jackson</artifactId> </dependency>
        ...
      </dependencies>
    </project>
  7. 将应用程序部署到 OSGi 容器时,请记住要为您选择的数据格式安装必要的功能。例如,如果您使用 Jackson 数据格式(默认),则通过输入以下 Karaf 控制台命令来安装 camel-jackson 功能:

    JBossFuse:karaf@root> features:install camel-jackson

    或者,如果您要部署到 Fabric 环境中,您可以将该功能添加到 Fabric 配置集中。例如,如果您使用配置集 MyRestProfile,您可以输入以下 console 命令来添加该功能:

    JBossFuse:karaf@root> fabric:profile-edit --features camel-jackson MyRestProfile

配置绑定模式

bindingMode 选项默认为 off,因此您必须明确配置它,以便启用 Java 对象的 marshalling。TABLE 显示支持的绑定模式列表。

注意

从 Camel 2.16.3 开始,只有在 content-type 标头包含 jsonxml 时,才会从 POJO 绑定到 JSon/JAXB。如果消息正文不应尝试使用绑定来总结,这允许您指定自定义 content-type。例如,当消息正文是一个自定义二进制有效负载时,这非常有用。

表 4.2. REST DSL BInding 模式
绑定模式描述

off

绑定关闭 (默认)

auto

为 JSON 和/或 XML 启用绑定。在此模式中,Camel 根据传入消息的格式自动选择 JSON 或 XML (JAXB)。但是,您不需要 启用这两种类型的数据格式:JSON 实现、XML 实现,也可以在 classpath 上提供。

json

仅为 JSON 启用绑定。必须在 classpath 上提供 JSON 实现(默认为 Camel 会尝试启用 camel-jackson 实现)。

xml

仅为 XML 启用绑定。必须在 classpath 上提供 XML 实现(默认情况下,Camel 会尝试启用 camel-jaxb 实现)。

json_xml

为 JSON 和 XML 启用绑定。在此模式中,Camel 根据传入消息的格式自动选择 JSON 或 XML (JAXB)。您需要在 classpath 提供两种数据格式。

在 Java 中,这些绑定模式值以以下 enum 类型的实例表示:

org.apache.camel.model.rest.RestBindingMode

您可以在多个不同的级别设置 bindingMode,如下所示:

REST DSL 配置

您可以从 restConfiguration 构建器设置 bindingMode 选项,如下所示:

restConfiguration().component("servlet").port(8181).bindingMode(RestBindingMode.json);
服务定义基础部分

您可以在 rest () 关键字后面立即设置 bindingMode 选项(在 verb 子句前面),如下所示:

rest("/user").bindingMode(RestBindingMode.json).get("/{id}").VerbClause
verb 子句

您可以在 verb 子句中设置 bindingMode 选项,如下所示:

rest("/user")
    .get("/{id}").bindingMode(RestBindingMode.json).to("...");

示例

如需完整的代码示例,演示了如何使用 REST DSL,将 Servlet 组件用作 REST 实施,请仔细查看 Apache Camel camel-example-servlet-rest-blueprint 示例。您可以通过安装独立 Apache Camel 发行版 apache-camel-2.23.2.fuse-7_10_0-00018-redhat-00001.zip,该示例在 Fuse 安装的 extras/ 子目录中提供的。

安装独立 Apache Camel 分发后,您可以在以下目录中找到示例代码:

ApacheCamelInstallDir/examples/camel-example-servlet-rest-blueprint

将 Servlet 组件配置为 REST 实施

camel-example-servlet-rest-blueprint 示例中,REST DSL 的底层实现由 Servlet 组件提供。Servlet 组件在 Blueprint XML 文件中配置,如 例 4.1 “为 REST DSL 配置 Servlet 组件” 所示。

例 4.1. 为 REST DSL 配置 Servlet 组件

<?xml version="1.0" encoding="UTF-8"?>
<blueprint ...>

  <!-- to setup camel servlet with OSGi HttpService -->
  <reference id="httpService" interface="org.osgi.service.http.HttpService"/>

  <bean class="org.apache.camel.component.servlet.osgi.OsgiServletRegisterer"
        init-method="register"
        destroy-method="unregister">
    <property name="alias" value="/camel-example-servlet-rest-blueprint/rest"/>
    <property name="httpService" ref="httpService"/>
    <property name="servlet" ref="camelServlet"/>
  </bean>

  <bean id="camelServlet" class="org.apache.camel.component.servlet.CamelHttpTransportServlet"/>
  ...
  <camelContext xmlns="http://camel.apache.org/schema/blueprint">

    <restConfiguration component="servlet"
                       bindingMode="json"
                       contextPath="/camel-example-servlet-rest-blueprint/rest"
                       port="8181">
      <dataFormatProperty key="prettyPrint" value="true"/>
    </restConfiguration>
    ...
  </camelContext>

</blueprint>

要使用 REST DSL 配置 Servlet 组件,您需要配置由以下三个层组成的堆栈:

REST DSL 层
REST DSL 层由 restConfiguration 元素配置,它通过将 component 属性设置为 servlet 的值来 与 Servlet 组件集成。
Servlet 组件层
Servlet 组件层作为类实例实施,CamelHttpTransportServlet,其中示例实例具有 bean ID camelServlet
HTTP 容器层

Servlet 组件必须部署到 HTTP 容器中。Karaf 容器通常配置有默认的 HTTP 容器(Jetty HTTP 容器),该容器侦听端口 8181 上的 HTTP 请求。要将 Servlet 组件部署到默认的 Jetty 容器,您需要执行以下操作:

  1. 获取对 org.osgi.service.http.HttpService OSGi 服务的 OSGi 参考,其中此服务是一个标准化的 OSGi 接口,提供对 OSGi 中默认 HTTP 服务器的访问。
  2. 创建 utility 类 OsgiServletRegisterer 实例,以在 HTTP 容器中注册 Servlet 组件。OsgiServletRegisterer 类是简化 Servlet 组件生命周期的实用程序。创建此类实例时,它会自动在 HttpService OSGi 服务上调用 registerServlet 方法;当实例被销毁时,它会自动调用 unregister 方法。

所需的依赖项

本例有两个依赖项,它们对 REST DSL 至关重要,如下所示:

Servlet 组件

提供 REST DSL 的底层实施。这在 Maven POM 文件中指定,如下所示:

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-servlet</artifactId>
  <version>${camel-version}</version>
</dependency>

在将应用程序捆绑包部署到 OSGi 容器之前,您必须安装 Servlet 组件功能,如下所示:

JBossFuse:karaf@root> features:install camel-servlet
jackson 数据格式

提供 JSON 数据格式实现。这在 Maven POM 文件中指定,如下所示:

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-jackson</artifactId>
  <version>${camel-version}</version>
</dependency>

在将应用程序捆绑包部署到 OSGi 容器之前,您必须安装 Jackson 数据格式功能,如下所示:

JBossFuse:karaf@root> features:install camel-jackson

用于响应的 Java 类型

示例应用在 HTTP Request 和 Response 消息中返回 User type 对象。用户 Java 类定义,如 例 4.2 “用于 JSON 响应的用户类” 所示。

例 4.2. 用于 JSON 响应的用户类

// Java
package org.apache.camel.example.rest;

public class User {

    private int id;
    private String name;

    public User() {
    }

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

用户 类以 JSON 数据格式具有相对简单的表示。例如,此类的典型实例以 JSON 格式表示:

{
    "id" : 1234,
    "name" : "Jane Doe"
}

使用 JSON 绑定的 REST DSL 路由示例

本例中的 REST DSL 配置和 REST 服务定义显示在 例 4.3 “使用 JSON 绑定的 REST DSL 路由” 中。

例 4.3. 使用 JSON 绑定的 REST DSL 路由

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           ...>
  ...
  <!-- a bean for user services -->
  <bean id="userService" class="org.apache.camel.example.rest.UserService"/>

  <camelContext xmlns="http://camel.apache.org/schema/blueprint">

    <restConfiguration component="servlet"
                       bindingMode="json"
                       contextPath="/camel-example-servlet-rest-blueprint/rest"
                       port="8181">
      <dataFormatProperty key="prettyPrint" value="true"/>
    </restConfiguration>

    <!-- defines the REST services using the  base path, /user -->
    <rest path="/user" consumes="application/json" produces="application/json">
      <description>User rest service</description>

      <!-- this is a rest GET to view a user with the given id -->
      <get uri="/{id}" outType="org.apache.camel.example.rest.User">
        <description>Find user by id</description>
        <to uri="bean:userService?method=getUser(${header.id})"/>
      </get>

      <!-- this is a rest PUT to create/update a user -->
      <put type="org.apache.camel.example.rest.User">
        <description>Updates or create a user</description>
        <to uri="bean:userService?method=updateUser"/>
      </put>

      <!-- this is a rest GET to find all users -->
      <get uri="/findAll" outType="org.apache.camel.example.rest.User[]">
        <description>Find all users</description>
        <to uri="bean:userService?method=listUsers"/>
      </get>

    </rest>

  </camelContext>

</blueprint>

REST 操作

例 4.3 “使用 JSON 绑定的 REST DSL 路由” 中的 REST 服务定义以下 REST 操作:

GET /camel-example-servlet-rest-blueprint/rest/user/{id}
获取 {id} 标识的用户详情,其中 HTTP 响应以 JSON 格式返回。
PUT /camel-example-servlet-rest-blueprint/rest/user
创建新用户,其中用户详情包含在 PUT 消息的正文中,以 JSON 格式编码(与 User 对象类型匹配)。
GET /camel-example-servlet-rest-blueprint/rest/user/findAll
获取 所有用户 的详情,其中 HTTP 响应以 JSON 格式返回为一组用户。

调用 REST 服务的 URL

通过检查来自 例 4.3 “使用 JSON 绑定的 REST DSL 路由” 的 REST DSL 定义,您可以将调用每个 REST 操作所需的 URL 组合在一起。例如,要调用第一个 REST 操作,它返回具有给定 ID 的用户详情,URL 如下:

http://localhost:8181
restConfiguration 中,协议默认为 http,端口明确设置为 8181
/camel-example-servlet-rest-blueprint/rest
restConfiguration 元素的 contextPath 属性指定。
/user
rest 元素的 path 属性指定。
/{id}
get verb 元素的 uri 属性指定。

因此,可以在命令行中输入以下命令来使用 curl 工具调用此 REST 操作:

curl -X GET -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user/123

同样,剩余的 REST 操作可以通过 curl 调用,方法是输入以下示例命令:

curl -X GET -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user/findAll

curl -X PUT -d "{ \"id\": 666, \"name\": \"The devil\"}" -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.