36.3. 使用注解实现类型转换器


概述

可以通过添加新的从类型转换器轻松自定义类型转换机制。这部分论述了如何实现从类型转换器以及如何将其与 Apache Camel 集成,以便注解类型转换器加载程序自动加载。

如何实现类型转换器

要实现自定义类型转换器,请执行以下步骤:

实施注解的转换器类

您可以使用 @Converter 注释实施自定义类型转换器类。您必须给类本身添加注解,以及用于执行类型转换的每个 静态方法。每个转换器方法都使用定义 from 类型的参数,可选择使用第二个 Exchange 参数,并且具有 定义要 类型的非void 返回值。类型转换器加载程序使用 Java 反映来查找注释的方法并将其集成到类型转换器机制中。例 36.3 “Annotated Converter 类示例” 显示一个注解的转换器类,它定义了一个从 java.io.File 转换为 java.io.InputStream 的转换器方法(使用 Exchange 参数),以及从 byte[] 转换为 String 的另一个转换器方法(使用 Exchange 参数)。

例 36.3. Annotated Converter 类示例

package com.YourDomain.YourPackageName;

import org.apache.camel.Converter;

import java.io.*;

@Converter
public class IOConverter {
    private IOConverter() {
    }

    @Converter
    public static InputStream toInputStream(File file) throws FileNotFoundException {
        return new BufferedInputStream(new FileInputStream(file));
    }

    @Converter
    public static String toString(byte[] data, Exchange exchange) {
        if (exchange != null) {
            String charsetName = exchange.getProperty(Exchange.CHARSET_NAME, String.class);
            if (charsetName != null) {
                try {
                    return new String(data, charsetName);
                } catch (UnsupportedEncodingException e) {
                    LOG.warn("Can't convert the byte to String with the charset " + charsetName, e);
                }
            }
        }
        return new String(data);
    }
}
Copy to Clipboard Toggle word wrap

toInputStream () 方法负责执行从 File 类型到 InputStream 类型的转换,而 toString () 方法负责执行从 byte[] 类型的转换到 String 类型。

注意

方法名称是 unimportant,可以是您选择的任何内容。重要的是参数类型、返回类型和存在 @Converter 注释。

创建一个 TypeConverter 文件

要为自定义转换器启用发现机制(由 注解类型转换器加载程序实现),请在以下位置创建一个 TypeConverter 文件:

META-INF/services/org/apache/camel/TypeConverter
Copy to Clipboard Toggle word wrap

TypeConverter 文件必须包含以逗号分隔的、类型为转换器类的完全限定域名(FQN)列表。例如,如果您希望类型转换器加载器在 YourPackageName.YourClassName 软件包中搜索被注解的转换器类,则 TypeConverter 文件将包含以下内容:

com.PackageName.FooClass
Copy to Clipboard Toggle word wrap

启用发现机制的替代方法是仅将软件包名称添加到 TypeConverter 文件中。例如,TypeConverter 文件将包含以下内容:

com.PackageName
Copy to Clipboard Toggle word wrap

这将导致软件包扫描程序通过 @Converter 标签的软件包扫描。使用 FQN 方法速度更快,这是首选的方法。

打包类型转换器

类型转换器作为 JAR 文件打包,其中包含自定义类型转换器和 META-INF 目录的编译类。将此 JAR 文件放在您的类路径上,使其可用于 Apache Camel 应用程序。

回退转换器方法

除了使用 @Converter 注释定义常规转换器方法外,您还可以选择使用 @FallbackConverter 注释来定义回退转换器方法。只有在主类型转换器无法在类型 registry 中查找常规转换器方法时,才会尝试回退转换器方法。

常规转换器方法和回退转换器之间的基本区别在于,常规转换器被定义为在特定类型对类型(例如,从 byte[]String)之间执行转换,而回退转换器 可以在任何 一对类型之间执行转换。它取决于回退转换器方法正文中的代码,以找出它可以执行的转换过程。在运行时,如果无法由常规转换器执行转换,主类型转换器会迭代每个可用的回退转换器,直到找到一个可以执行转换。

回退转换器的方法签名可以具有以下形式之一:

// 1. Non-generic form of signature
@FallbackConverter
public static Object MethodName(
    Class type,
    Exchange exchange,
    Object value,
    TypeConverterRegistry registry
)

// 2. Templating form of signature
@FallbackConverter
public static <T> T MethodName(
    Class<T> type,
    Exchange exchange,
    Object value,
    TypeConverterRegistry registry
)
Copy to Clipboard Toggle word wrap

其中 MethodName 是回退转换器的任意方法名称。

例如,以下代码提取(从文件组件实施中)显示了一个回退转换器,它可以转换 GenericFile 对象的正文,利用类型转换器已存在于类型转换器 registry 中:

package org.apache.camel.component.file;

import org.apache.camel.Converter;
import org.apache.camel.FallbackConverter;
import org.apache.camel.Exchange;
import org.apache.camel.TypeConverter;
import org.apache.camel.spi.TypeConverterRegistry;

@Converter
public final class GenericFileConverter {

    private GenericFileConverter() {
        // Helper Class
    }

    @FallbackConverter
    public static <T> T convertTo(Class<T> type, Exchange exchange, Object value, TypeConverterRegistry registry) {
        // use a fallback type converter so we can convert the embedded body if the value is GenericFile
        if (GenericFile.class.isAssignableFrom(value.getClass())) {
            GenericFile file = (GenericFile) value;
            Class from = file.getBody().getClass();
            TypeConverter tc = registry.lookup(type, from);
            if (tc != null) {
                Object body = file.getBody();
                return tc.convertTo(type, exchange, body);
            }
        }

        return null;
    }
    ...
}
Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2025 Red Hat