{ "name":"John Doe", "dob":"01/01/1970", "emailAddresses":[ { "type":"home", "address":"john.doe@gmail.com" }, { "type":"work", "address":"jdoe@bigco.com" } ]}
JSON Support Reference
JSON, short for JavaScript Object Notation, is a lightweight data interchange format. It is a text-based, human-readable format for representing simple data structures and associative arrays (called objects).
Object bindings
Mule support binding JSON data to objects and marshaling Java object to JSON using the Jackson Framework. Jackson uses annotations to describe how data is mapped to a Java object model. For example, let’s say we have an JSON file that describes a person. When we receive JSON data we want to convert into a Person
object, the JSON looks like this:
We also have an object Person
we want to create from the JSON data. We use annotations to describe how to perform the mapping. We use the @JsonAutoDetect
to say that field member names map directly to JSON field names:
@JsonAutoDetectpublic class Person{ private String name; private String dob; private List<EmailAddress> emailAddresses; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDob() { return dob; } public void setDob(String dob) { this.dob = dob; } public List<EmailAddress> getEmailAddresses() { return emailAddresses; } public void setEmailAddresses(List<EmailAddress> emailAddresses) { this.emailAddresses = emailAddresses; }}
The EmailAddress
object that is used in the emailAddresses is just another JavaBean with the @JsonAutoDetect
annotation.
At this point Mule can figure out whether to perform a JSON transforms based on the parameters of the method being called. For example:
public class PersonComponent { public void processPerson(@Payload Person person) { //tickle }}
Here we would receive the contents of the people.json
file above on an endpoint, Mule would see that Person.class
is an annotated JSON object and that we had received JSON data from the JMS queue and perform the conversion.
Global JSON Mapper
Jackson performs mappings through the ObjectMapper
. This is an object that can be configured with other configuration about how to serialise data and define mixins that add annotations to objects that you cannot change directly. It is possible to define a global ObjectMapper
; a single mapper that’s used for all JSON transforms in your application. This is not required since Mule automatically creates a mapper for a transformer, but using a global mapper can be useful if you need to configure specific properties on the mapper or use mixins. To create a shared ObjectMapper
Add the following to your Mule configuration file:
<json:mapper name="myMapper"> <json:mixin mixinClass="org.mule.module.json.transformers.FruitCollectionMixin" targetClass="org.mule.module.json.transformers.FruitCollection"/> <json:mixin mixinClass="org.mule.module.json.transformers.AppleMixin" targetClass="org.mule.tck.testmodels.fruit.Apple"/></json:mapper>
Intercepting JSON Transforms
So far we have discussed how Mule performs automatic JSON transforms. Sometimes you may want to intercept the transform, to do this just create a transformer with a method return or parameter type of your JSON class:
@Transformer(sourceTypes = {InputStream.class})public Person toPerson(String json, ObjectMapper mapper) throws JAXBException{ return (Person)mapper.readValue(in, Person.class);}
The ObjectMapper
either creates an instance for you or uses the global context for your application. One reason for doing this is to strip out some JSON elements and create objects from a subset of the JSON received. For more information about transforms, see the Using Transformers section.
JSON Path
There is no standard language currently for querying JSON data graphs in the same way XPATH can query XML documents. Mule has created a simple query syntax for working with JSON data in Java, called JsonPath.
This query syntax provides a simple way to navigate a JSON data structure. The following JSON data demonstrates how JSON Path queries can be used.
{ "name":"John Doe", "dob":"01/01/1970", "emailAddresses":[ { "type":"home", "address":"john.doe@gmail.com" }, { "type":"work", "address":"jdoe@bigco.com" } ]}
To select a child entry use:
name
To access array data, use square braces with an index value:
emailAddresses[0]/type
Or where the route element is an array:
[0]/arrayElement
Also, multi-dimensional arrays can be accessed using:
filters[1]/init[1][0]
This is rare, but if a JSON property name contains a '/', the name needs to be single quoted:
results/'http://foo.com'/value
JSON Path in Expressions
JSON Path can be used in Mule expressions to query JSON message payloads for filtering or enrichment.
For example, to use JSON Path to perform content based routing:
<choice> <when expression="emailAddresses[0]/type = 'home'" evaluator="json"> <append-string-transformer message="Home address is #[json:emailAddresses[0]/address]" /> </when> <when expression="emailAddresses[0]/type = 'work'" evaluator="json"> <append-string-transformer message="Work address is #[json:emailAddresses[0]/address]" /> </when> <otherwise> <append-string-transformer message="No email address found" /> </otherwise></choice>
The expression evaluator name is 'json', the expression is any valid JSON Path expression.
Note: When doing boolean expressions such as in the example above, these operators are supported:
Operator | Example |
---|---|
= |
|
!= |
|
String comparisons need to be in single quotes, 'null' is recognised as null, and boolean comparisons are supported. If checking numeric values, just treat them as a string.
Transformers
These are transformers specific to this transport. Note that these are added automatically to the Mule registry at start up. When doing automatic transformations these will be included when searching for the correct transformers.
Name | Description |
---|---|
json-to-object-transformer |
A transformer that will convert a JSON encoded object graph to a java object. The object type is determined by the 'returnClass' attribute. Note that this transformers supports Arrays and Lists. For example, to convert a JSON string to an array of org.foo.Person, set the |
object-to-json-transformer |
Converts a java object to a JSON encoded object that can be consumed by other languages such as Javascript or Ruby. The JSON Object mapper can be configured using the |
Filters
Filters can be used to control which data is allowed to continue in the flow.
Name | Description |
---|---|
is-json-filter |
A filter that will determine if the current message payload is a JSON encoded message. |