Apache Camel指南-第六章:路由径构建之转换消息内容

创建Exchange实例

总览

当使用Java代码处理消息时(例如,在Bean类或处理器类中),通常需要创建一个新的交换实例。如果需要创建Exchange对象,最简单的方法是调用ExchangeBuilder类的方法,如此处所述。

ExchangeBuilder类

ExchangeBuilder该类 的完全限定名称如下:

org.apache.camel.builder.ExchangeBuilder

ExchangeBuilder公开静态方法anExchange,你可以用它开始建立一个交换对象。

例如,以下代码创建一个新的交换对象,其中包含消息正文字符串Hello World!,以及带有用户名和密码凭据的标头:

// Java
import org.apache.camel.Exchange;
import org.apache.camel.builder.ExchangeBuilder;
...
Exchange exch = ExchangeBuilder.anExchange(camelCtx)
                    .withBody("Hello World!")
                    .withHeader("username", "jdoe")
                    .withHeader("password", "pass")
                    .build();

ExchangeBuilder方法

ExchangeBuilder类支持下列方法:

  • ExchangeBuilder anExchange(CamelContext context)

    (静态方法)启动构建交换对象。

  • Exchange build()

    建立交流。

  • ExchangeBuilder withBody(Object body)

    在交易所上设置消息正文(即,设置交易所的“ **入站”**消息正文)。

  • ExchangeBuilder withHeader(String key, Object value)

    在交易所上设置标题(即,在交易所的In消息上设置标题)。

  • ExchangeBuilder withPattern(ExchangePattern pattern)

    在交易所上设置交易所模式。

  • ExchangeBuilder withProperty(String key, Object value)

    在交易所上设置属性。

转换邮件内容

抽象

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

简单消息转换

总览

Java DSL具有内置的API,使您可以对传入和传出消息执行简单的转换。下图显示的规则将文本追加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命令可以直接插入到路由器规则-例如,setBody()在命令下图显示了ProcessorDefinition与转换消息内容有关的方法:

表2.5。ProcessorDefinition类的转换方法

方法 描述
Type convertBodyTo(Class type) 将IN消息主体转换为指定的类型。
Type removeFaultHeader(String name) 添加一个处理器,该处理器删除FAULT消息上的标头。
Type removeHeader(String name) 添加一个处理器,该处理器除去IN消息上的标头。
Type removeProperty(String name) 添加一个删除交换属性的处理器。
ExpressionClause> setBody() 添加一个将主体设置在IN消息上的处理器。
Type setFaultBody(Expression expression) 添加一个将主体设置为FAULT消息的处理器。
Type setFaultHeader(String name, Expression expression) 添加一个在FAULT消息上设置标头的处理器。
ExpressionClause> setHeader(String name) 添加一个在IN消息上设置标头的处理器。
Type setHeader(String name, Expression expression) 添加一个在IN消息上设置标头的处理器。
ExpressionClause> setOutHeader(String name) 添加一个在OUT消息上设置标题的处理器。
Type setOutHeader(String name, Expression expression) 添加一个在OUT消息上设置标题的处理器。
ExpressionClause> setProperty(String name) 添加一个设置交换属性的处理器。
Type setProperty(String name, Expression expression) 添加一个设置交换属性的处理器。
ExpressionClause> transform() 添加一个将主体设置在OUT消息上的处理器。
Type transform(Expression expression) 添加一个将主体设置在OUT消息上的处理器。
建造者类

org.apache.camel.builder.Builder类提供对上下文中的消息内容,其中表达式或谓词的预期。换句话说,Builder通常在DSL命令的参数中调用方法,下表总结了该类中可用的静态方法。

表2.6。Builder类中的方法

方法 描述
static ValueBuilder body() 返回交易所中入站主体的谓词和值构建器。
static ValueBuilder bodyAs(Class type) 以特定类型返回入站邮件正文的谓词和值生成器。
static ValueBuilder constant(Object value) 返回一个常量表达式。
static ValueBuilder faultBody() 返回交换上的故障主体的谓词和值生成器。
static ValueBuilder faultBodyAs(Class type) 以特定类型返回故障消息正文的谓词和值生成器。
static ValueBuilder header(String name) 返回交换头上的谓词和值构建器。
static ValueBuilder outBody() 返回交易所中出站主体的谓词和值构建器。
static ValueBuilder outBodyAs(Class type) 以特定类型返回出站邮件正文的谓词和值生成器。
static ValueBuilder property(String name) 返回交易所属性的谓词和值构建器。
static ValueBuilder regexReplaceAll(Expression content, String regex, Expression replacement) 返回一个表达式,该表达式用给定的替换替换所有出现的正则表达式。
static ValueBuilder regexReplaceAll(Expression content, String regex, String replacement) 返回一个表达式,该表达式用给定的替换替换所有出现的正则表达式。
static ValueBuilder sendTo(String uri) 返回一个表达式,该表达式处理到给定端点uri的交换。
static ValueBuilder systemProperty(String name) 返回给定系统属性的表达式。
static ValueBuilder systemProperty(String name, String defaultValue) 返回给定系统属性的表达式。
ValueBuilder类

org.apache.camel.builder.ValueBuilder类可以通过修改返回值Builder的方法。换句话说,这些方法ValueBuilder提供了一种修改消息内容的简单方法。下表总结了ValueBuilder该类中可用的方法。

表2.7。ValueBuilder类中的修饰符方法

方法 描述
ValueBuilder append(Object value) 用给定值追加此表达式的字符串求值。
Predicate contains(Object value) 创建一个谓词,使左手表达式包含右手表达式的值。
ValueBuilder convertTo(Class type) 使用注册的类型转换器将当前值转换为给定类型。
ValueBuilder convertToString() 使用注册的类型转换器将当前值转换为String。
Predicate endsWith(Object value)
T evaluate(Exchange exchange, Class type)
Predicate in(Object… values)
Predicate in(Predicate… predicates)
Predicate isEqualTo(Object value) 如果当前值等于给定value参数,则返回true 。
Predicate isGreaterThan(Object value) 如果当前值大于给定value参数,则返回true 。
Predicate isGreaterThanOrEqualTo(Object value) 如果当前值大于或等于给定value参数,则返回true 。
Predicate isInstanceOf(Class type) 如果当前值是给定类型的实例,则返回true。
Predicate isLessThan(Object value) 如果当前值小于给定value参数,则返回true 。
Predicate isLessThanOrEqualTo(Object value) 如果当前值小于或等于给定value参数,则返回true 。
Predicate isNotEqualTo(Object value) 如果当前值不等于给定value参数,则返回true 。
Predicate isNotNull() 如果当前值不是,则返回true null
Predicate isNull() 如果当前值为,则返回true null
Predicate matches(Expression expression)
Predicate not(Predicate predicate) 否定谓词参数。
ValueBuilder prepend(Object value) 将此表达式的字符串评估添加到给定值。
Predicate regex(String regex)
ValueBuilder regexReplaceAll(String regex, Expression replacement) 用给定的替换替换正则表达式的所有出现。
ValueBuilder regexReplaceAll(String regex, String replacement) 用给定的替换替换正则表达式的所有出现。
ValueBuilder regexTokenize(String regex) 使用给定的正则表达式标记该表达式的字符串转换。
ValueBuilder sort(Comparator comparator) 使用给定的比较器对当前值进行排序。
Predicate startsWith(Object value) 如果当前值与value参数的字符串值匹配,则返回true 。
ValueBuilder tokenize() 使用逗号标记分隔符来标记此表达式的字符串转换。
ValueBuilder tokenize(String token) 使用给定的令牌分隔符对此表达式的字符串转换进行令牌化。

编组和拆组

Java DSL命令

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

  • marshal() —将高级数据格式转换为低级数据格式。
  • unmarshal()—将低级数据格式转换为高级数据格式。
资料格式

Apache Camel支持以下数据格式的编组和解组:

  • Java serialization
  • JAXB
  • XMLBeans
  • XStream
JaJava serialization

使您能够将Java对象转换为二进制数据的blob。对于这种数据格式,解组可将二进制blob转换为Java对象,而编组可将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,解组可将XML数据类型转换为Java对象,而解组可将Java对象转换为XML数据类型。在使用JAXB数据格式之前,必须使用JAXB编译器编译XML模式,以生成表示模式中XML数据类型的Java类。这称为绑定架构。绑定模式之后,您可以使用以下代码定义规则以将XML数据解组到Java对象。

org.apache.camel.spi.DataFormat jaxb = new org.apache.camel.model.dataformat.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,解组可将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,解组可将XML数据类型转换为Java对象,而编组可将Java对象转换为XML数据类型。

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

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

端点绑定

什么是绑定?

在Apache Camel中,绑定是将端点包装在合同中的一种方式,例如,通过应用数据格式,Content Enricher或验证步骤。将条件或转换应用于传入的消息,并将补充条件或转换应用于传入的消息。

数据格式绑定

DataFormatBinding这里你要定义类是特定情况下有用的绑定负责接受和特定的数据格式。在这种情况下,创建绑定所需要做的就是创建一个DataFormatBinding实例,并将引用传递给构造函数中的相关数据格式。

示例中的XML DSL代码片段显示了一个绑定(具有ID,jaxb),该绑定能够在与Apache Camel端点关联时对JAXB数据格式进行编组和解编:

<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>
将绑定与端点关联

下列替代方法可用于将绑定与端点关联:

  • Binding URI
  • Component
Binding URI

要将绑定与端点关联,可以在端点URI前面加上,其中绑定的bean ID(例如,在Spring XML中创建的绑定bean的ID)。 binding:*NameOfBinding*``*NameOfBinding*

例如,以下示例显示如何将ActiveMQ端点与JAXB绑定中定义的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前缀。现在,您可以将jaxbmqID用作端点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构造函数

BindingComponent类支持下面的构造函数:

  • public BindingComponent()

    没有参数形式。使用属性注入来配置绑定组件实例。

  • public BindingComponent(Binding binding)

    将此绑定组件与指定Binding对象关联binding

  • public BindingComponent(Binding binding, String uriPrefix)

    将此绑定组件与指定的Binding对象binding和URI前缀关联uriPrefix。这是最常用的构造函数。

  • public BindingComponent(Binding binding, String uriPrefix, String uriPostfix)

    此构造函数支持其他URI后缀uriPostfix参数,该参数会自动附加到使用此绑定组件定义的任何URI。

实施自定义绑定

除了DataFormatBinding用于编组和解组数据格式的,您还可以实现自己的自定义绑定。定义自定义绑定,如下所示:

  1. 实现一个org.apache.camel.Processor类,以对传入到使用者端点(出现在from元素中)的消息执行转换。
  2. 实现一个互补org.apache.camel.Processor类,以对从生产者端点(出现在to元素中)发出的消息执行反向转换。
  3. 实现org.apache.camel.spi.Binding接口,该接口充当处理器实例的工厂。
绑定界面

下面的例子显示了接口的定义org.apache.camel.spi.Binding,您必须实现该接口才能定义自定义绑定。

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

import org.apache.camel.Processor;

/**
 * Represents a Binding or contract
 * which can be applied to an Endpoint; such as ensuring that a particular
 * Data Format 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();
}
何时使用绑定

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

你可能感兴趣的:(apache,java-ee,集成学习)