2.6. 转换消息内容


摘要

Apache Camel 支持各种转换消息内容的方法。除了用于修改消息内容的简单原生 API 外,Apache Camel 还支持与多个不同的第三方库和转换标准集成。

2.6.1. 简单消息转换

概述

Java DSL 内置 API,可让您在传入和传出消息上执行简单的转换。例如,例 2.1 “诊断消息的简单转换” 中显示的规则将文本 World! 附加至传入消息正文的末尾。

例 2.1. 诊断消息的简单转换

from("SourceURL").setBody(body().append(" World!")).to("TargetURL");

其中 setBody () 命令取代了传入消息正文的内容。

用于简单转换的 API

您可以使用以下 API 类在路由器规则中执行消息内容的简单转换:

  • org.apache.camel.model.ProcessorDefinition
  • org.apache.camel.builder.Builder
  • org.apache.camel.builder.ValueBuilder

ProcessorDefinition 类

org.apache.camel.model.ProcessorDefinition 类定义 DSL 命令,您可以直接插入到路由器规则的所有流量中,例如 例 2.1 “诊断消息的简单转换” 中的 setBody () 命令。表 2.5 “来自 ProcessorDefinition Class 的转换方法” 显示与转换消息内容相关的 ProcessorDefinition 方法:

表 2.5. 来自 ProcessorDefinition Class 的转换方法
方法描述

类型 convertBodyTo (Class type)

将 IN 消息正文转换为指定的类型。

类型 removeFaultHeader (String name)

添加一个处理器,以删除 FAULT 消息上的标头。

类型 removeHeader (String name)

添加删除 IN 消息上的标头的处理器。

类型 removeProperty (字符串名称)

添加删除交换属性的处理器。

ExpressionClause<ProcessorDefinition<Type>> setBody()

添加在 IN 消息上设置正文的处理器。

类型 setFaultBody (Expression 表达式)

添加一个处理器,在 FAULT 消息上设置正文。

类型 setFaultHeader (String name, Expression expression)

添加一个处理器,在 FAULT 消息上设置标头。

ExpressionClause<ProcessorDefinition<Type>> setHeader(String name)

添加一个处理器,用于设置 IN 消息上的标头。

类型 setHeader (String name, Expression expression)

添加一个处理器,用于设置 IN 消息上的标头。

ExpressionClause<ProcessorDefinition<Type>> setOutHeader(String name)

添加在 OUT 消息上设置标头的处理器。

类型 setOutHeader (String name, Expression expression)

添加在 OUT 消息上设置标头的处理器。

ExpressionClause<ProcessorDefinition<Type>> setProperty(String name)

添加设置交换属性的处理器。

类型 setProperty (字符串名称、表达式表达式)

添加设置交换属性的处理器。

ExpressionClause<ProcessorDefinition<Type>> transform()

添加在 OUT 消息上设置正文的处理器。

类型转换(Expression 表达式)

添加在 OUT 消息上设置正文的处理器。

构建器类

org.apache.camel.builder.Builder 类在符合表达式或 predicates 时提供对消息内容的访问。换句话说,构建器 方法通常会在 DSL 命令 parameter 中调用,例如 例 2.1 “诊断消息的简单转换” 中的 body () 命令。表 2.6 “Builder 类的方法” 总结了 Builder 类中提供的静态方法。

表 2.6. Builder 类的方法
方法描述

static <E extends Exchange> ValueBuilder<E> body()

在交换上为入站正文返回 predicate 和值构建器。

静态 <E 扩展 Exchange,T> ValueBuilder<E> bodyAs (Class<T> type)

以特定类型形式返回入站消息正文的 predicate 和值构建器。

static <E 扩展 Exchange> ValueBuilder<E> constant (Object value)

返回恒定表达式。

static <E extends Exchange> ValueBuilder<E> faultBody()

在交换上为错误正文返回 predicate 和值构建器。

静态 <E 扩展 Exchange,T> ValueBuilder<E> faultBodyAs (Class<T> type)

以特定类型形式返回错误消息正文的 predicate 和值构建器。

static <E 扩展 Exchange> ValueBuilder<E> 标头(字符串名称)

为交换上的标头返回 predicate 和值构建器。

static <E extends Exchange> ValueBuilder<E> outBody()

在交换上为出站正文返回 predicate 和值构建器。

static <E 扩展 Exchange> ValueBuilder<E> outBodyAs (Class<T> type)

以特定类型形式返回出站消息正文的 predicate 和值构建器。

static ValueBuilder 属性(String name)

为交换上的属性返回 predicate 和值构建器。

static ValueBuilder regexReplaceAll(Expression content, String regex, Expression replacement)

返回用所给替换替换所有正则表达式的表达式。

static ValueBuilder regexReplaceAll(Expression content, String regex, String replacement)

返回用所给替换替换所有正则表达式的表达式。

静态 ValueBuilder sendTo (String uri)

返回将交换发送到给定端点 uri 的表达式。

static <E 扩展 Exchange> ValueBuilder<E> systemProperty (字符串名称)

返回给定系统属性的表达式。

static <E extends Exchange> ValueBuilder<E> systemProperty(String name, String defaultValue)

返回给定系统属性的表达式。

ValueBuilder 类

org.apache.camel.builder.ValueBuilder 类可让您修改 Builder 方法返回的值。换句话说,ValueBuilder 中的方法提供了修改消息内容的简单方法。表 2.7 “修饰符来自于 ValueBuilder Class” 总结了 ValueBuilder 类中可用的方法。也就是说,表中仅显示用于修改它们的值的方法(了解详细信息,请参阅 API 参考文档 )。

表 2.7. 修饰符来自于 ValueBuilder Class
方法描述

ValueBuilder<E> append (Object value)

使用给定值附加此表达式的字符串评估。

predicate 包含(Object 值)

创建一个 predicate,左手表达式包含右手表达式的值。

ValueBuilder<E> convertTo (Class type)

使用注册类型转换器将当前值转换为给定类型。

ValueBuilder<E> convertToString()

使用注册类型转换器将当前值转换为 String。

predicate 结束With (Object 值)

 

<T> T evaluate (Exchange Exchange, Class<T> type)

 

predicate in (Object…​ value)

 

predicate in (Predicate…​ predicates)

 

predicate 是EqualTo (Object value)

返回 true,如果当前值等于给定 参数。

predicate isGreaterThan (Object value)

如果当前值大于给定 参数,则返回 true。

predicate isGreaterThanOrEqualTo (Object value)

如果当前值大于或等于给定 参数,则返回 true。

predicate 是InstanceOf (Class 类型)

如果当前值是给定类型的实例,则返回 true。

predicate isLessThan (Object value)

如果当前值小于给定 参数,则返回 true。

predicate isLessThanOrEqualTo (Object value)

返回 true,如果当前值小于或等于给定 参数。

predicate isNotEqualTo (Object value)

返回 true,如果当前值不等于给定 参数。

Predicate isNotNull()

返回 true,如果当前值不是 null

Predicate isNull()

返回 true,如果当前值为 null

predicate 匹配(Expression 表达式)

 

predicate not (Predicate predicate)

negates predicate 参数。

ValueBuilder prepend (Object value)

将此表达式的字符串评估添加到给定值。

predicate regex (字符串正则表达式)

 

ValueBuilder<E> regexReplaceAll (String regex、Expression<E> 替换)

使用给定替换替换正则表达式的所有冲突。

ValueBuilder<E> regexReplaceAll (字符串 regex、String 替换)

使用给定替换替换正则表达式的所有冲突。

ValueBuilder<E> regexTokenize (String regex)

使用给定的正则表达式来令牌此表达式的字符串转换。

ValueBuilder sort (组合器比较器)

使用给定的比较器对当前值进行排序。

predicate 启动With (Object 值)

如果当前值与 value 参数的值匹配,则返回 true。

ValueBuilder<E> tokenize()

使用逗号令牌分隔符来令牌此表达式的字符串转换。

ValueBuilder<E> tokenize (String token)

使用给定的令牌分隔符来令牌此表达式的字符串转换。

2.6.2. marshalling 和 Unmarshalling

Java DSL 命令

您可以使用以下命令在低级别和高级别消息格式间转换:

  • marshal () •- Converts a high-level data format to a low-level data format。
  • unmarshal () •- Converts a low-level data format to a high-level data format。

数据格式

Apache Camel 支持对以下数据格式进行 marshalling 和 unmarshalling:

  • Java 序列化
  • JAXB
  • XMLBeans
  • XStream

Java 序列化

允许您将 Java 对象转换为二进制数据的 blob。对于这种数据格式,将二进制 blob 转换为 Java 对象,并通过 marshalling 将 Java 对象转换为二进制 blob。例如,若要从端点 SourceURL 读取序列化 Java 对象,并将其转换为 Java 对象,您可以使用如下规则:

from("SourceURL").unmarshal().serialization()
.<FurtherProcessing>.to("TargetURL");

或者,在 Spring XML 中:

<camelContext id="serialization" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="SourceURL"/>
    <unmarshal>
      <serialization/>
    </unmarshal>
    <to uri="TargetURL"/>
  </route>
</camelContext>

JAXB

提供 XML 模式类型和 Java 类型之间的映射(请参阅 https://jaxb.dev.java.net/)。对于 JAXB,unmarshalling 可将 XML 数据类型转换为 Java 对象,marshalling 可将 Java 对象转换为 XML 数据类型。在使用 JAXB 数据格式前,您必须使用 JAXB 编译器编译 XML 模式,以生成代表架构中 XML 数据类型的 Java 类。这称为 绑定 schema。在绑定了 schema 后,您可以使用类似如下的代码定义将 XML 数据解封到 Java 对象的规则:

org.apache.camel.spi.DataFormat jaxb = new org.apache.camel.converter.jaxb.JaxbDataFormat("GeneratedPackageName");

from("SourceURL").unmarshal(jaxb)
.<FurtherProcessing>.to("TargetURL");

其中生成了 Packagename 是 JAXB 编译器生成的 Java 软件包的名称,其中包含代表您的 XML 模式的 Java 类。

或者,在 Spring XML 中:

<camelContext id="jaxb" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="SourceURL"/>
    <unmarshal>
      <jaxb prettyPrint="true" contextPath="GeneratedPackageName"/>
    </unmarshal>
    <to uri="TargetURL"/>
  </route>
</camelContext>

XMLBeans

提供 XML 模式类型和 Java 类型之间的备选映射(请参阅 http://xmlbeans.apache.org/)。对于 XMLBeans,取消marshalling 将 XML 数据类型转换为 Java 对象并汇总 Java 对象转换为 XML 数据类型。例如,要使用 XMLBeans 将 XML 数据发封至 Java 对象,您可以使用类似如下的代码:

from("SourceURL").unmarshal().xmlBeans()
.<FurtherProcessing>.to("TargetURL");

或者,在 Spring XML 中:

<camelContext id="xmlBeans" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="SourceURL"/>
    <unmarshal>
      <xmlBeans prettyPrint="true"/>
    </unmarshal>
    <to uri="TargetURL"/>
  </route>
</camelContext>

XStream

提供 XML 类型和 Java 类型之间的另外映射(请参阅 http://www.xml.com/pub/a/2004/08/18/xstream.html)。XStream 是一个序列化库(如 Java 序列化),可让您将任何 Java 对象转换为 XML。对于 XStream,unmarshalling 可将 XML 数据类型转换为 Java 对象,marshalling 会将 Java 对象转换为 XML 数据类型。

from("SourceURL").unmarshal().xstream()
.<FurtherProcessing>.to("TargetURL");
注意

Spring XML 当前不支持 XStream 数据格式。

2.6.3. 端点绑定

什么是绑定?

在 Apache Camel 中,绑定 是一种在 contract 中嵌套端点的方法,例如,通过应用数据格式、内容增强或验证步骤来嵌套端点。条件或转换适用于即将进入的消息,并将互补条件或转换应用到消息。

DataFormatBinding

对于您要定义 marshals 和 unmarshals 是一个特定数据格式的绑定,DataFormatBinding 类对特定数据格式很有用。第 2.6.2 节 “marshalling 和 Unmarshalling”在这种情况下,您需要创建绑定的过程都是创建一个 DataFormatBinding 实例,传递对构造器中相关数据格式的引用。

例如,例 2.2 “JAXB Binding” 中的 XML DSL 片断显示一个绑定(带有 ID、jaxb)的绑定(带有 ID、jaxb ),在与 Apache Camel 端点相关联时,它可以编出 JAXB 数据格式:

例 2.2. JAXB Binding

<beans ... >
    ...
    <bean id="jaxb" class="org.apache.camel.processor.binding.DataFormatBinding">
        <constructor-arg ref="jaxbformat"/>
    </bean>

    <bean id="jaxbformat" class="org.apache.camel.model.dataformat.JaxbDataFormat">
        <property name="prettyPrint" value="true"/>
        <property name="contextPath" value="org.apache.camel.example"/>
    </bean>

</beans>

将绑定与端点关联

以下的 alternatives 可用于将绑定与端点相关联:

绑定 URI

要将绑定与端点关联,您可以将端点 URI 与 binding:NameOfBinding 为前缀,其中 NameOfBinding 是绑定的 Bean ID (例如,Spring XML 中创建绑定 ID)。

例如,以下示例显示了如何将 ActiveMQ 端点与 例 2.2 “JAXB Binding” 中定义的 JAXB 绑定关联。

<beans ...>
    ...
    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="binding:jaxb:activemq:orderQueue"/>
            <to uri="binding:jaxb:activemq:otherQueue"/>
        </route>
    </camelContext>
    ...
</beans>

BindingComponent

您不需要使用前缀来与端点关联,而是让关联隐式,以便该绑定不需要出现在 URI 中。对于没有隐式绑定的现有端点,达到此目的的最简单方法是使用 BindingComponent 类嵌套端点。

例如,要将 jaxb 绑定与 activemq 端点关联,您可以定义一个新的 BindingComponent 实例,如下所示:

<beans ... >
    ...
    <bean id="jaxbmq" class="org.apache.camel.component.binding.BindingComponent">
        <constructor-arg ref="jaxb"/>
        <constructor-arg value="activemq:foo."/>
    </bean>

    <bean id="jaxb" class="org.apache.camel.processor.binding.DataFormatBinding">
        <constructor-arg ref="jaxbformat"/>
    </bean>

    <bean id="jaxbformat" class="org.apache.camel.model.dataformat.JaxbDataFormat">
        <property name="prettyPrint" value="true"/>
        <property name="contextPath" value="org.apache.camel.example"/>
    </bean>

</beans>

其中(可选)第二个构造器参数到 jaxbmq 定义 URI 前缀。现在,您可以使用 jaxbmq ID 作为端点 URI 的方案。例如,您可以使用此绑定组件定义以下路由:

<beans ...>
    ...
    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="jaxbmq:firstQueue"/>
            <to uri="jaxbmq:otherQueue"/>
        </route>
    </camelContext>
    ...
</beans>

前面的路由等同于以下路由,它使用绑定 URI 方法:

<beans ...>
    ...
    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="binding:jaxb:activemq:foo.firstQueue"/>
            <to uri="binding:jaxb:activemq:foo.otherQueue"/>
        </route>
    </camelContext>
    ...
</beans>
注意

对于实施自定义 Apache Camel 组件的开发人员,可以通过实施从 org.apache.camel.spi.HasBinding 接口继承的端点类来实现此目的。

BindingComponent constructors

BindingComponent 类支持以下构造器:

public BindingComponent()
无参数形式。使用属性注入配置绑定组件实例。
public BindingComponent(Binding binding)
将此绑定组件与指定的 绑定 对象 绑定 相关联。
public BindingComponent(Binding binding, String uriPrefix)
将此绑定组件与指定的 Binding 对象、绑定和 URI 前缀关联。uriPrefix。这是最常用的构造器。
public BindingComponent (Binding binding, String uriPrefix, String uriPostfix)
这个构造器支持额外的 URI post-fix, uriPostfix 的参数,该参数自动附加到使用此绑定组件定义的任何 URI。

实现自定义绑定

除了用于 marshalling 和 unmarshalling 数据格式的 DataFormatBinding 外,您还可以实施自己的自定义绑定。定义自定义绑定,如下所示:

  1. 实施 org.apache.camel.Processor 类,对传入消费者端点的消息进行转换( 元素中讲)。
  2. 实施互补 org.apache.camel.Processor 类,对来自生产端点( 应用到 元素)传出的消息执行反向转换。
  3. 实施 org.apache.camel.spi.Binding 接口,该接口充当处理器实例的工厂。

绑定接口

例 2.3 “org.apache.camel.spi.Binding 接口” 显示 org.apache.camel.spi.Binding 接口的定义,您必须实施这些接口来定义自定义绑定。

例 2.3. org.apache.camel.spi.Binding 接口

// Java
package org.apache.camel.spi;

import org.apache.camel.Processor;

/**
 * Represents a <a href="http://camel.apache.org/binding.html">Binding</a> or contract
 * which can be applied to an Endpoint; such as ensuring that a particular
 * <a href="http://camel.apache.org/data-format.html">Data Format</a> is used on messages in and out of an endpoint.
 */
public interface Binding {

    /**
     * Returns a new {@link Processor} which is used by a producer on an endpoint to implement
     * the producer side binding before the message is sent to the underlying endpoint.
     */
    Processor createProduceProcessor();

    /**
     * Returns a new {@link Processor} which is used by a consumer on an endpoint to process the
     * message with the binding before its passed to the endpoint consumer producer.
     */
    Processor createConsumeProcessor();
}

何时使用绑定

当您需要将同一类型转换应用到许多不同类型的端点时,绑定非常有用。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.