[CONF] Apache Camel: Type Converter (page edited)

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[CONF] Apache Camel: Type Converter (page edited)

Dhiraj Bokde (Confluence)

Type Converter has been edited by Claus Ibsen (Sep 03, 2008).

Change summary:

CAMEL-837

(View changes)

Content:

Type Converter

Its very common when routing messages from one endpoint to another to need to convert the body payloads from one type to another such as to convert to and from the following common types

  • File
  • String
  • byte[] and ByteBuffer
  • InputStream and OutputStream
  • Reader and Writer
  • Document and Source

The Message interface defines a helper method to allow conversions to be done via the getBody(Class) method.

So in an endpoint you can convert a body to another type via

Message message = exchange.getIn();
Document document = message.getBody(Document.class);

How Type Conversion works

The type conversion strategy is defined by the TypeConverter interface which can be customized on a CamelContext.

The default implementation, DefaultTypeConverter uses pluggable strategies to load type converters via TypeConverterLoader. The default strategy, AnnotationTypeConverterLoader uses a discovery mechanism to find converters.

Discovering Type Converters

The AnnotationTypeConverterLoader will search the classpath for a file called META-INF/services/org/apache/camel/TypeConverter. The contents are expected to be comma separated package names. These packages are then recursively searched for any objects with the @Converter annotation. Then any method marked with @Converter is assumed to be a conversion method; where the parameter is the from value and the return is the to value.

e.g. the following shows how to register a converter from File -> InputStream

@Converter
public class IOConverter {

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

Static methods are invoked; non-static methods require an instance of the converter object to be created (which is then cached). If a converter requires configuration you can plug in an Injector interface to the DefaultTypeConverter which can construct and inject converter objects via Spring or Guice.

We have most of the common converters for common Java types in the org.apache.camel.converter package and its children.

Writing your own Type Converters

You are welcome to write your own converters. Remember to use the @Converter annotations on the classes and methods you wish to use. Then add the packages to a file called META-INF/services/org/apache/camel/TypeConverter in your jar. Remember to make sure that :-

  • static methods are encouraged to reduce caching; but instance methods are fine, particularly if you want to allow optional dependency injection to customize the converter
  • converter methods should be thread safe and reentrant

Encoding support for byte[] and String Conversion

Available in Camel 1.5

Since Java provides converting the byte[] to String and String to byte[] with the charset name parameter. You can define the charset name by setting the exchange property name Exchange.CHARSET_NAME with the charset name, such as "UTF-8" or "iso-8859-1".

Exchange parameter

Available in Camel 1.5

The type converter accepts the Exchange as an optional 2nd parameter. This is usable if the type converter for instance needs information from the current exchange. For instance combined with the encoding support its possible for type converters to convert with the configured encoding. An example from camel-core for the byte[] -> String converter:

@Converter
    public static String toString(byte[] data, Exchange exchange) {
        if (exchange != null) {
            String charsetName = (String) exchange.getProperty(Exchange.CHARSET_NAME);
            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);
    }