2.6. 转换消息内容
摘要
Apache Camel 支持各种转换消息内容的方法。除了用于修改消息内容的简单原生 API 外,Apache Camel 还支持与几个不同的第三方库和转换标准集成。
2.6.1. 简单消息转换
概述
Java DSL 具有一个内置 API,可让您对传入和传出消息执行简单的转换。例如,例 2.1 “Incoming 消息的简单转换” 中显示的规则会将文本 World!
附加到传入消息正文的末尾。
例 2.1. Incoming 消息的简单转换
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 命令,您可以直接插入到路由器规则 swig-wagon 中,例如: 中的 setBody ()
命令。表 2.5 “来自 ProcessorDefinition 类的转换方法” 显示与转换消息内容相关的 ProcessorDefinition
方法:
方法 | 描述 |
---|---|
| 将 IN 消息正文转换为指定的类型。 |
| 添加处理器,它将删除 FAULT 消息上的标头。 |
| 添加处理器,它将删除 IN 消息上的标头。 |
| 添加删除交换属性的处理器。 |
| 添加处理器,该处理器在 IN 消息上设置正文。 |
| 添加处理器,在 FAULT 消息上设置正文。 |
| 添加处理器,在 FAULT 消息上设置标头。 |
| 添加在 IN 消息上设置标头的处理器。 |
| 添加在 IN 消息上设置标头的处理器。 |
| 添加处理器,该处理器在 OUT 消息上设置标头。 |
| 添加处理器,该处理器在 OUT 消息上设置标头。 |
| 添加设置交换属性的处理器。 |
| 添加设置交换属性的处理器。 |
| 添加处理器,该处理器在 OUT 消息上设置正文。 |
| 添加处理器,该处理器在 OUT 消息上设置正文。 |
builder 类
org.apache.camel.builder.Builder
类提供在预期表达式或 predicates 的上下文中访问消息内容。换句话说,构建程序
方法通常在 DSL 命令的参数 中调用,例如: 例 2.1 “Incoming 消息的简单转换” 中的 body ()
命令。表 2.6 “Builder 类中的方法” 总结了 Builder
类中提供的静态方法。
方法 | 描述 |
---|---|
| 为交换上的入站正文返回 predicate 和 value 构建器。 |
| 返回作为特定类型的入站消息正文的 predicate 和 value 构建器。 |
| 返回恒定表达式。 |
| 返回交换上错误正文的 predicate 和 value 构建器。 |
| 返回作为特定类型的 fault 消息正文的 predicate 和 value 构建器。 |
| 为交换上的标头返回 predicate 和 value builder。 |
| 为交换上的出站正文返回 predicate 和 value 构建器。 |
| 返回作为特定类型的出站消息正文的 predicate 和 value 构建器。 |
| 为交换的属性返回 predicate 和 value builder。 |
| 返回一个表达式,该表达式将所有正则表达式的出现替换为所给的替换。 |
| 返回一个表达式,该表达式将所有正则表达式的出现替换为所给的替换。 |
| 返回将交换发送到给定端点 uri 的表达式。 |
| 返回给定系统属性的表达式。 |
| 返回给定系统属性的表达式。 |
ValueBuilder 类
org.apache.camel.builder.ValueBuilder
类允许您修改由 Builder
方法返回的值。换句话说,ValueBuilder
中的方法提供了修改消息内容的简单方法。表 2.7 “ValueBuilder 类中的修饰符方法” 总结了 ValueBuilder
类中提供的方法。也就是说,表格仅显示用于修改所调用值的方法(有关完整详情,请参阅 API 参考文档 )。
方法 | 描述 |
---|---|
| 使用给定值附加此表达式的字符串评估。 |
| 创建一个 predicate,使左侧表达式包含右手表达式的值。 |
| 使用注册类型转换器将当前值转换为给定类型。 |
| 使用注册类型转换器将当前值转换为 String。 |
| |
| |
| |
| |
|
如果当前值等于给定 |
|
如果当前值大于给定 |
|
如果当前值大于或等于给定 |
| 如果当前的值是给定类型的实例,则返回 true。 |
|
如果当前值小于给定 |
|
如果当前值小于或等于给定 |
|
如果当前值不等于给定 |
|
如果当前值不是 |
|
如果当前值为 |
| |
| 对 predicate 参数进行求值。 |
| 将这个表达式的字符串评估添加到给定值。 |
| |
| 使用给定的替换替换正则表达式的所有情况。 |
| 使用给定的替换替换正则表达式的所有情况。 |
| 使用给定的正则表达式,令牌将此表达式的字符串转换。 |
| 使用给定比较器对当前的值进行排序。 |
|
如果当前值与 |
| 使用逗号分隔此表达式的字符串转换。 |
| 使用给定令牌分隔符对这个表达式的字符串转换进行令牌转换。 |
2.6.2. Marshalling 和 Unmarshalling
Java DSL 命令
您可以使用以下命令在低级和高级别消息格式之间进行转换:
-
marshal ()
swig-wagon 将高级别数据格式转换为低级数据格式。 -
unmarshal ()
swig-wagon 将低级数据格式转换为高级数据格式。
数据格式
Apache Camel 支持对以下数据格式的 marshalling 和 unmarshalling:
- Java serialization
- JAXB
- XMLBeans
- XStream
Java serialization
允许您将 Java 对象转换为二进制数据的 blob。对于此数据格式,unmarshalling 将二进制 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 后,您可以使用类似如下的代码为 Java 对象定义 unmarshal XML 数据的规则:
org.apache.camel.spi.DataFormat jaxb = new org.apache.camel.converter.jaxb.JaxbDataFormat("GeneratedPackageName"); from("SourceURL").unmarshal(jaxb) .<FurtherProcessing>.to("TargetURL");
其中 GeneratedPackagename 是 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,unmarshalling 将 XML 数据类型转换为 Java 对象,marshalling 将 Java 对象转换为 XML 数据类型。例如,要使用 XMLBeans 将 unmarshal 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 swig-rhacm 中,例如通过应用 Data Format、Content Enricher 或验证步骤。条件或转换应用到来自消息,并将补充条件或转换应用到消息。
DataFormatBinding
DataFormatBinding
类对于您要定义 marshals 和 unmarshals 特定数据格式的绑定很有用(请参阅 第 2.6.2 节 “Marshalling 和 Unmarshalling”)。在这种情况下,您需要做的所有创建绑定都是创建一个 DataFormatBinding
实例,在构造器中传递对相关数据格式的引用。
例如,例 2.2 “JAXB Binding” 中的 XML DSL 片段显示一个绑定(带有 ID,jaxb
),该绑定可以在与 Apache Camel 端点关联时 marshalling 和 unmarshalling 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>
将绑定与端点关联
以下替代方案可用于将绑定与端点关联:
绑定 URI
要将绑定与端点关联,您可以使用 binding:NameOfBinding
为端点 URI 前缀,其中 NameOfBinding
是绑定的 bean ID (例如,在 Spring XML 中创建的绑定 bean 的 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
类支持以下 constructors:
public BindingComponent()
- 没有参数表单。使用属性注入配置绑定组件实例。
public BindingComponent (Binding binding)
-
将此绑定组件与指定的
Binding
对象关联,绑定
。 public BindingComponent (Binding binding, String uriPrefix)
-
将此绑定组件与指定的
Binding
对象、绑定和
URI 前缀uriPrefix
关联。这是最常用的构造器。 public BindingComponent (Binding binding, String uriPrefix, String uriPostfix)
-
此构造器支持额外的 URI 后修复,即
uriPostfix
、参数,该参数会自动附加到使用此绑定组件定义的任何 URI。
实现自定义绑定
除了 DataFormatBinding
外,它用于 marshalling 和 unmarshalling 数据格式,您可以实施自己的自定义绑定。定义自定义绑定,如下所示:
-
实施
org.apache.camel.Processor
类,以对传入到消费者端点的消息执行转换(在from
元素中)。 -
实施补充的
org.apache.camel.Processor
类,对从生成者端点传出的消息执行反向转换(在to
元素中出现)。 -
实施
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(); }
何时使用绑定
当您需要将相同类型转换到许多不同类型的端点时,绑定很有用。