Working with Transformers
Transformers in iBeans are used to convert messages from one data type to another. You can also use any of the Mule transformers, so it is possible to transform data using XSLT, XQuery, or any other Mule transformer.
Creating Transformers
In their simplest form, transformers convert between different Java types. You create a transformer by performing the conversion in a method that you annotate with the @Transformer annotation:
At runtime, this method will be discovered and registered with Mule. Then, whenever an Mule needs to convert from a String to a URL, this transformer will be used.
Here we take an input of java.lang.String, this is referred to as the source type and convert it to a java.net.URL, this is referred to as the return type.
If you create a transformer with the same source and return types as one of the standard transformers provided with Mule, your custom transformer will be given priority and used instead. Be careful not to create multiple transformers with the same source and return types, or an exception will be thrown due to multiple transformers matching the exact same source and return types. |
Note that the method throws MalformedURLException, which is an exception specific to creating URL objects. It's good practice to just re-throw any exceptions thrown in a transformer method and let the container handle them.
Working with Collections
The Mule transformation system support generics with collections, this means that transforms can be matched against collections of a specific type of object. To extend the example above, we could have a transformer that created a List of URL objects from a comma-separated list of URL strings.
It is good practice to always provide types for any transforms that deal with collections. Doing so will provide more accurate information to Mule about how to match your transformers and it provides better type checking in your code. |
Multiple Source Types
Transformers can only have one return type but we can define multiple source types. For example, lets say we might receive the URL string as s java.lang.String or java.io.InputStream we could add the additional source type to the @Transformer annotation. Note that you can add a comma-separated list of source type classes.
Now if a request is made to convert a a java.io.InputStream to a java.net.URL, this transformer would be discovered and behind the scenes Mule would attempt to convert java.io.InputStream to String before calling the method. Note there needs to be a transformer registered that will convert a java.io.InputStream to java.lang.String and Mule provides a selection of default transformers for dealing with JDK types such as String, byte arrays, InputStreams, Xml Documents, etc. But if you need a transform that doesn't exist you can just create a new transform method.
Working with XML and JSON
Not in Mule 3.0 codebase yet |
Most services deal with data formatted using XML or JSON (JavaScript Object Notation). Mule supports binding objects to XML and vice-versa using JAXB (Java API for XML binding) which is standard in JDK 6. JSON marshaling to objects and back again using a JSON parsing framework called Jackson. These frameworks are supported automatically by Mule. For more information see Using Bindings.
Accessing Message Headers
All messages in Mule have headers. If you need to access the headers, add a parameter to the transformer method signature annotated with the @InboundHeaders annotation:
The '*' indicates that all headers should be returned. Alternatively, you can specify a single header name and just return the value of that header:
To receive a subset of headers, you can list them as comma-separated values:
By default an error will be thrown if a listed header is not on the response. To avoid this error, mark the header as optional with '?'. For example, X-MyHeader is optional in the following code:
If the return type for the @InboundHeaders param is a java.util.List, just the values will be returned.
Transformer Rules
- Transformers must be defined in their own class, e.g.,
org.me.MyTransformers. You can have one or more transformer methods in the class, and each will be discoverable inside iBeans. - If a transformer has state, all transformers defined in that class will share that state.
- Primitive types must not be used for transformer method return types. Only objects can be used.
- For collections use Lists or Sets, not arrays. Generics are supported and should be used where ever possible since the generic types are also using when trying to match transformers.
- The transformer methods must be public and concrete implementations, the
@Transformerannotation cannot be used on an interface. - The transform method must have at least one parameter and and non-void return type.
java.lang.Objectcannot be used for the parameter types or return type.