4.3. 到 Java 对象和从 Java 对象进行复制


用于通过 HTTP 传输的 Java 对象

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

JSON

JSON (JavaScript 对象表示法)是一个轻量级数据格式,可轻松映射到 Java 对象或从 Java 对象映射。JSON 语法是紧凑的,易于输入,易于读和写。出于所有这些原因,JSON 已经成为 REST 服务的消息格式。

例如,以下 JSON 代码可以代表具有两个属性字段 idnameUser bean:

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

JAXB (适用于 XML 绑定的 Java 架构)是基于 XML 的数据格式,可轻松映射到 Java 对象或从 Java 对象映射。要将 XML 汇集到 Java 对象,您还必须注解要使用的 Java 类。

例如,以下 JAXB 代码可以代表具有两个属性字段 idnameUser bean:

<?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 上下文应包含 CamelJaxbObjectFactory 属性,值为 true。但是,由于优化,默认值为 false。

JSON 和 JAXB 与 REST DSL 集成

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

  • 自动对 Java 对象和从 Java 对象进行 Marshalling (因为适当的配置)。
  • 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)

如何启用对象 marshalling

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

  1. 启用绑定模式,通过设置 bindingMode 选项(您可以在多个级别中,您可以设置绑定模式 swig-wagon 以获得详细信息,请参阅 “配置绑定模式”一节)。
  2. 使用 type 选项(必需)在传入消息中指定要转换为(或 from)的 Java 类型 (可选),在传出消息中使用 outType 选项(可选)。
  3. 如果要将 Java 对象转换为 JAXB 数据格式,您必须记得使用适当的 JAXB 注释给 Java 类添加注解。
  4. 使用 jsonDataFormat 选项和/或 xmlDataFormat 选项(可以在 restConfiguration 构建器中指定)指定底层数据格式实现(或实现)。
  5. 如果您的路由以 JAXB 格式提供返回值,您通常要将交换正文的 Out 消息设置为带有 JAXB 注释( JAXB 元素)的类实例。但是,如果您想以 XML 格式直接提供 JAXB 返回值,请将 dataFormatProperty 设置为 key xml.out.mustBeJAXBElement,它可在 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 console 命令安装 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 的绑定。如果消息正文不应该尝试使用绑定进行 marshalled,则这允许您指定自定义 content-type。例如,当消息正文是自定义二进制有效负载时,这很有用。

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

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("...");

Example

如需完整的代码示例,显示如何使用 REST DSL (将 Servlet 组件用作 REST 实施),请查看 Apache Camel camel-example-servlet-rest-blueprint 示例。您可以通过安装独立 Apache Camel 分发 apache-camel-2.23.2.fuse-7_13_0-00013-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 方法;当实例被销毁时,它会自动调用未注册的方法。

所需的依赖项

这个示例有两个依赖项,它们对 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
Jacks data format

提供 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 类型

example 应用在 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;
    }
}

User 类采用 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} 标识的用户的详细信息,其中以 JSON 格式返回 HTTP 响应。
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

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

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.