架构

转换器

师成师成· 更新于 2026-09-28· 阅读 18 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

Transformer

Transformer(org.apache.camel.spi.Transformer)根据路由定义中声明的输入类型(Input Type)和/或输出类型(Output Type),对消息执行声明式的转换,该路由定义声明了期望的消息类型。默认的 Camel 消息实现了 DataTypeAware 接口,因而能够保存由 DataType 表示的消息类型。

如果路由定义中通过输入类型和/或输出类型声明了输入类型和/或输出类型,并且该类型与运行时的实际消息类型不同,Camel 的内部处理器就会查找一个能将当前消息类型转换为期望消息类型的 Transformer 并加以应用。一旦转换成功,或者消息本身已经处于期望类型,消息的数据类型就会被更新。

数据类型格式

scheme:name

其中 scheme 是数据模型的类型,如 java、xml 或 json,而 name 是各个数据类型的名称。scheme 也可以表示 Camel 组件的 scheme,例如 http 或 aws2-s3,以便引用组件特有的数据类型。使用 java scheme 时,数据类型名称可以是完整的类名(例如 java:org.apache.camel.Foo)。如果只指定 scheme,则会匹配该 scheme 下的所有数据类型,类似于通配符的效果。

支持的转换器

转换器说明
数据格式转换器使用数据格式进行转换
端点转换器使用端点进行转换
自定义转换器使用自定义转换器类进行转换。转换器必须是 org.apache.camel.spi.Transformer 的子类
加载转换器加载多个转换器实现(例如通过注解类路径扫描)。同时会预加载已知的 Camel 默认转换器实现

通用选项

所有转换器都具有以下通用选项,用于指定转换器支持的数据类型。必须指定 name,或者同时指定 fromType 和 toType。

名称说明
scheme所支持的数据类型 scheme。可以直接引用一个 scheme,例如 xml 或 json。比如指定 xml 后,该转换器将应用于所有 java -> xml 以及 xml -> java 的转换。
name转换器的名称。如果指定了名称,用户可以在路由中使用 scheme 与 name 的组合(例如 xml:Order)来引用该转换器。
fromType要转换的源数据类型。
toType要转换的目标数据类型。

转换器的实现可以使用 scheme:name 或 fromType/toType 的组合作为标识符。

使用 scheme:name 标识符时,用户可以在路由中通过其完整名称来引用该转换器。

在这里我们声明该路由具有指定的预期输入类型:

  • Java
  • XML
  • YAML
from("direct:abc")
    .inputType("myScheme:myTransformer")
    .to("log:abc");
<route>
    <from uri="direct:abc"/>
    <inputType urn="myScheme:myTransformer"/>
    <to uri="log:abc"/>
</route>
- route:
    inputType:
      urn: myScheme:myTransformer
    from:
      uri: direct:abc
      steps:
        - to:
            uri: "log:abc"

如前所述,转换器也可以省略名称,仅使用 scheme(例如 xml),以应用于给定 scheme 的所有数据类型转换(例如 xml:Order、xml:OrderResponse、xml:anything)。

当使用 fromType/toType 组合标识时,转换器会根据 Camel 路由中使用的给定数据类型(例如 inputType)以及给定的 Exchange 数据类型(由 Exchange 消息通过 DataTypeAware 接口指定)自动进行匹配。

总体而言,转换器解析机制在搜索从给定数据类型到给定数据类型的合适转换时,会尝试找到最佳匹配。该机制首先尝试查找 fromType 和 toType 的精确匹配,然后是通配符匹配(仅使用给定数据类型 scheme 的转换器),接着是使用 scheme:name 标识的命名转换器,最后是仅匹配 scheme 的命名转换器。

如果配置中尚未预加载,转换器解析机制还会通过工厂查找器资源路径查找,对转换器实现进行延迟加载。

DataFormat 转换器选项

名称描述
type数据格式类型
ref数据格式 ID 的引用

以下示例指定 Bindy DataFormat 类型:

  • Java
  • XML
  • YAML
BindyDataFormat bindy = new BindyDataFormat();
bindy.setType(BindyType.Csv);
bindy.setClassType(com.example.Order.class);

transformer()
    .fromType(com.example.Order.class)
    .toType("csv:CSVOrder")
    .withDataFormat(bindy);
<transformers>
    <dataFormatTransformer fromType="java:com.example.Order" toType="csv:CSVOrder">
        <bindy id="csvdf" type="Csv" classType="com.example.Order"/>
    </dataFormatTransformer>
</transformers>
- transformers:
    dataFormatTransformer:
      fromType: java:com.example.Order
      toType: "csv:CSVOrder"
      bindy:
        type: "Csv"
        classType: "com.example.Order"

端点转换器选项

名称描述
ref端点 ID 的引用
uri端点 URI

下面是一个在 Java DSL 中指定端点 URI 的示例:

  • Java
  • XML
  • YAML
transformer()
    .fromType("xml")
    .toType("json")
    .withUri("component:componentPathOptions?mappingFile=myMapping.xml");
<transformers>
    <endpointTransformer uri="component:componentPathOptions?mappingFile=myMapping.xml" fromType="xml" toType="json"/>
</transformers>
- transformers:
    endpointTransformer:
      uri: component:componentPathOptions?mappingFile=myMapping.xml
      fromType: xml
      toType: json

自定义转换器选项

请注意,Transformer 必须是 org.apache.camel.spi.Transformer 的子类。

名称说明
ref自定义 Transformer Bean 的 ID 引用
className自定义 Transformer 类的完全限定类名

以下是指定自定义 Transformer 类的示例:

  • Java
  • XML
  • YAML
transformer()
    .fromType("xml")
    .toType("json")
    .withJava(com.example.MyCustomTransformer.class);
<transformers>
    <customTransformer className="com.example.MyCustomTransformer" fromType="xml" toType="json"/>
</transformers>
- transformers:
    customTransformer:
      className: com.example.MyCustomTransformer
      fromType: xml
      toType: json

加载 Transformer 选项

用户可以预加载已知的默认 transformer,也可以通过类路径扫描来加载 transformer。

名称说明
defaults加载已知的默认 transformer 实现(例如 plain-text、application-octet-stream)
location用于扫描 transformer 实现的类路径位置。transformer 实现必须使用 org.apache.camel.spi.DataTypeTransformer 注解,才能被扫描器识别。

以下是加载默认 Transformer 类的示例:

  • Java
  • XML
  • YAML
transformer()
    .withDefaults();
<transformers>
    <loadTransformer defaults="true"/>
</transformers>
- transformers:
    loadTransformer:
      defaults: true

以下是一个通过类路径扫描加载 Transformer 类的示例:

  • Java
  • XML
  • YAML
transformer()
    .scan("org.apache.camel.transformer.standard");
<transformers>
    <loadTransformer packageScan="org.apache.camel.transformer.standard"/>
</transformers>
- transformers:
    loadTransformer:
      packageScan: "org.apache.camel.transformer.standard"

类路径扫描会查找使用了 org.apache.camel.spi.DataTypeTransformer 注解的类。该注解用于定义转换器的名称以及(或者)所支持的源/目标数据类型。

@DataTypeTransformer(name = "uppercase")
public class UppercaseDataTypeTransformer extends Transformer {

    @Override
    public void transform(Message message, DataType fromType, DataType toType) {
        message.setBody(message.getBody(String.class).toUpperCase());
    }
}

示例

例如,要声明一个使用 xslt 组件将 xml:ABCOrder 转换为 xml:XYZOrder 的 Endpoint Transformer,可以按如下方式操作:

  • Java
  • XML
  • YAML
transformer()
    .fromType("xml:ABCOrder")
    .toType("xml:XYZOrder")
    .withUri("xslt:transform.xsl");
<transformers>
    <endpointTransformer uri="xslt:transform.xsl" fromType="xml:ABCOrder" toType="xml:XYZOrder"/>
</transformers>
- transformers:
    endpointTransformer:
      uri: xslt:transform.xsl
      fromType: xml:ABCOrder
      toType: xml:XYZOrder

如果你有如下的路由定义,那么上面的 Transformer 将会在 direct:abc 端点把消息发送给 direct:xyz 时被应用:

  • Java
  • XML
  • YAML
from("direct:abc")
    .inputType("xml:ABCOrder")
    .to("direct:xyz");

from("direct:xyz")
    .inputType("xml:XYZOrder")
    .to("somewhere:else");
<routes>
    <route>
        <from uri="direct:abc"/>
        <inputType urn="xml:ABCOrder"/>
        <to uri="direct:xyz"/>
    </route>
    <route>
        <from uri="direct:xyz"/>
        <inputType urn="xml:XYZOrder"/>
        <to uri="somewhere:else"/>
    </route>
</routes>
- route:
    inputType:
      urn: xml:ABCOrder
    from:
      uri: direct:abc
      steps:
        - to:
            uri: direct:xyz
- route:
    inputType:
      urn: xml:XYZOrder
    from:
      uri: direct:xyz
      steps:
        - to:
            uri: somewhere:else

另请参阅

Validator 是与之相关的功能。

评论

登录后参与评论

正在加载评论…