34.2. 消息


概述

消息对象代表使用以下抽象模型的消息:

  • 消息正文
  • 消息标头
  • 消息附加

消息正文和消息标头可以是任意类型(它们声明为类型 Object),并且消息附加声明为 javax.activation.DataHandler 类型,其中可以包含任意 MIME 类型。如果您需要获取消息内容的具体表示,您可以使用类型转换器机制将正文和标头转换为其他类型的,并可能使用 marshalling 和 unmarshalling 机制。

Apache Camel 消息的一个重要特性是,它们支持 lazy 创建 消息正文和标头。在某些情况下,这意味着消息可以通过路由,而无需完全解析。

Message 接口

org.apache.camel.Message 接口定义了访问消息正文、消息标头和消息附加的方法,如 例 34.2 “邮件接口” 所示。

例 34.2. 邮件接口

// Access the message body
Object getBody();
<T> T  getBody(Class<T> type);
void   setBody(Object body);
<T> void setBody(Object body, Class<T> type);

// Access message headers
Object getHeader(String name);
<T> T  getHeader(String name, Class<T> type);
void   setHeader(String name, Object value);
Object removeHeader(String name);
Map<String, Object> getHeaders();
void setHeaders(Map<String, Object> headers);

// Access message attachments
javax.activation.DataHandler getAttachment(String id);
java.util.Map<String, javax.activation.DataHandler> getAttachments();
java.util.Set<String> getAttachmentNames();
void addAttachment(String id, javax.activation.DataHandler content)

// Access the message ID
String getMessageId();
void   setMessageId(String messageId);

有关 Message 接口方法的完整描述,请参考 第 44.1 节 “消息接口”

lazy 创建正文、标头和附加

Apache Camel 支持 lazy 创建正文、标头和附加功能。这意味着,在需要前,不会创建代表消息正文、消息标头或消息附加的对象。

例如,请考虑以下路由,该路由从 In 消息访问 foo 消息标头:

from("SourceURL")
    .filter(header("foo")
    .isEqualTo("bar"))
    .to("TargetURL");

在此路由中,如果我们假定 SourceURL 引用的组件支持 lazy 创建,则不会实际解析 In 消息标头,直到执行 标头("foo") 调用为止。此时,底层的消息实现会解析标头并填充标头映射。在到达路由的末尾之前,消息正文 不会解析,在 to ("TargetURL") 调用中。此时,正文会被转换为写入目标端点 TargetURL 所需的格式。

通过等待最后可能的时间,然后再填充正文、标头和附加功能,您可以确保避免不必要的类型转换。在某些情况下,您可以完全避免解析。例如,如果路由不包含对消息标头的显式引用,消息可以在不解析标头的情况下遍历路由。

实践中是否实施了 lazy 创建,这取决于底层组件的实施。通常,当创建消息正文、消息标头或消息附件成本时,lazy 创建非常重要。有关实现支持延迟创建的消息类型的详情,请参考 第 44.2 节 “实施消息接口”

lazy 创建消息 ID

Apache Camel 支持消息 ID 的 lazy 创建。也就是说,只有在您实际调用 getMessageId () 方法时才会生成消息 ID。此方法的 DefaultExchange.getExchangeId () 实现将 ID 生成委派给通过 CamelContext 注册的 UUID 生成器。

如果端点实现实现,如果端点实现需要唯一消息 ID 的协议,则一些端点实现会隐式调用 getMessageId () 方法。特别是,JMS 消息通常包含一个包含唯一消息 ID 的标头,因此 JMS 组件自动调用 getMessageId () 来获取消息 ID (这由 JMS 端点上的 messageIdEnabled 选项控制)。

有关如何使用 CamelContext 注册 UUID 生成器的详情,请参考 第 34.4 节 “built-In UUID Generators”

初始消息格式

In 消息的初始格式由源端点决定,Out 消息的初始格式由目标端点决定。如果底层组件支持 lazy 创建,则消息将保持未解析状态,直到应用程序明确访问为止。大多数 Apache Camel 组件以相对原始形式的 raw 格式创建消息正文,例如,使用 byte[], ByteBuffer,InputStream, 或 OutputStream 等类型来代表它。这样可确保创建初始消息所需的开销最小。在需要更详细的信息格式时,组件通常依赖 类型转换器汇总处理器

类型转换器

消息的初始格式无关紧要,因为您可以使用内置的类型转换器(请参阅 第 34.3 节 “built-In Type Converters”)轻松地将消息从一个格式转换为另一个格式。Apache Camel API 中有多种方法公开类型转换功能。例如,可以将 convertBodyTo (Class type) 方法插入到路由中,以转换 In 消息的正文,如下所示:

from("SourceURL").convertBodyTo(String.class).to("TargetURL");

其中 In 消息的正文转换为 java.lang.String。以下示例演示了如何将字符串附加到 In 消息正文的末尾:

from("SourceURL").setBody(bodyAs(String.class).append("My Special Signature")).to("TargetURL");

在为末尾附加字符串前,消息正文转换为字符串格式。本例中不需要显式转换消息正文。您还可以使用:

from("SourceURL").setBody(body().append("My Special Signature")).to("TargetURL");

其中 append () 方法会自动将消息正文转换为字符串,然后附加其参数。

在消息中键入转换方法

org.apache.camel.Message 接口公开一些明确执行类型转换的方法:

  • getBody (Class<T> type) HEKETI-wagonReturns the message body as type, T.
  • getHeader (String name, Class<T> type) swig-wagonReturns named 标头值,作为 type、T

有关支持的转换类型的完整列表,请参阅 第 34.3 节 “built-In Type Converters”

转换为 XML

除了支持简单类型(如 byte[]、Serte BufferString 等)之间的转换外,内置的类型转换器还支持转换为 XML 格式。例如,您可以将消息正文转换为 org.w3c.dom.Document 类型。这个转换比简单的转换更昂贵,因为它涉及解析整个消息,然后创建代表 XML 文档结构的节点树。您可以转换为以下 XML 文档类型:

  • org.w3c.dom.Document
  • javax.xml.transform.sax.SAXSource

XML 类型转换具有比更简单的转换更小的适用性。因为并非所有消息正文都符合 XML 结构,所以您必须记住这种类型的转换可能会失败。另一方面,在许多情况下,路由器只处理 XML 消息类型。

Marshalling 和 unmarshalling

Marshalling 涉及将高级别格式转换为低级格式,unmarshaling 涉及将低级格式转换为高级别格式。以下两个处理器用于在路由中执行 marshalling 或 unmarshalling:

  • marshal()
  • unmarshal()

例如,要从文件中读取序列化 Java 对象,并将它 unmarshal 到 Java 对象,您可以使用 例 34.3 “unmarshalling a Java Object” 中显示的路由定义。

例 34.3. unmarshalling a Java Object

from("file://tmp/appfiles/serialized")
    .unmarshal()
    .serialization()
    .<FurtherProcessing>
    .to("TargetURL");

最终消息格式

In 消息到达路由的末尾时,目标端点必须能够将消息正文转换为可写入物理端点的格式。相同的规则适用于到达源端点的 Out 消息。此转换通常使用 Apache Camel 类型转换器隐式执行。通常,这涉及从低级格式转换为另一个低级别格式,如从 byte[] 数组转换为 InputStream 类型。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.