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"
}
Copy to Clipboard Toggle word wrap
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>
Copy to Clipboard Toggle word wrap
注意

从 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>
    Copy to Clipboard Toggle word wrap
  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>
    Copy to Clipboard Toggle word wrap
  7. 将应用程序部署到 OSGi 容器时,请记住要为您选择的数据格式安装必要的功能。例如,如果您使用 Jackson 数据格式(默认),则通过输入以下 Karaf 控制台命令来安装 camel-jackson 功能:

    JBossFuse:karaf@root> features:install camel-jackson
    Copy to Clipboard Toggle word wrap

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

    JBossFuse:karaf@root> fabric:profile-edit --features camel-jackson MyRestProfile
    Copy to Clipboard Toggle word wrap

配置绑定模式

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

注意

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

Expand
表 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
Copy to Clipboard Toggle word wrap

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

REST DSL 配置

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

restConfiguration().component("servlet").port(8181).bindingMode(RestBindingMode.json);
Copy to Clipboard Toggle word wrap
服务定义基础部分

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

rest("/user").bindingMode(RestBindingMode.json).get("/{id}").VerbClause
Copy to Clipboard Toggle word wrap
verb 子句

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

rest("/user")
    .get("/{id}").bindingMode(RestBindingMode.json).to("...");
Copy to Clipboard Toggle word wrap

示例

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

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

ApacheCamelInstallDir/examples/camel-example-servlet-rest-blueprint
Copy to Clipboard Toggle word wrap

将 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>
Copy to Clipboard Toggle word wrap

要使用 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>
Copy to Clipboard Toggle word wrap

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

JBossFuse:karaf@root> features:install camel-servlet
Copy to Clipboard Toggle word wrap
jackson 数据格式

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

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-jackson</artifactId>
  <version>${camel-version}</version>
</dependency>
Copy to Clipboard Toggle word wrap

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

JBossFuse:karaf@root> features:install camel-jackson
Copy to Clipboard Toggle word wrap

用于响应的 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;
    }
}
Copy to Clipboard Toggle word wrap

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

{
    "id" : 1234,
    "name" : "Jane Doe"
}
Copy to Clipboard Toggle word wrap

使用 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>
Copy to Clipboard Toggle word wrap

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
Copy to Clipboard Toggle word wrap

同样,剩余的 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
Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2025 Red Hat