public class ShippingService
{
public ShippingConfirmation makeShippingRequest(Customer customer, Item[] items, DataHandler supportingDocumentation)
{
//do stuff
}
}
Using Expressions
Expressions allow you to extract information from the current message or determine how to handle the message. Expressions are very useful with routers and filters for defining routing logic and for filtering out unwanted messages.
Mule ESB provides several default expression evaluators, allowing you to embed expression logic in a variety of expression languages, or you can create your own evaluators to support additional languages.
This page describes how to use expressions. For more details on how to configure expressions, see Expressions Configuration Reference.
Message Property Scopes
Starting with Mule 3 expressions operating on message properties also support an optional scope qualifier syntax. Read Message Property Scopes for more info.
Using Expressions with Transformers
This section describes the transformers that support expressions. For more information on transformers, see Using Transformers.
Expression Transformer
The expression transformer executes one or more expressions on the current message where the result of the expression(s) will become the payload of the current message.
For example, imagine you have a service component with a message signature that accepts three arguments:
And the message being passed to you component looks like this:
public interface ShippingRequestMessage
{
public Customer getCustomer();
public Item[] getShippingItems();
//etc
}
The <expression-transformer>
can be used to extract the fields from the ShippingRequestMessage
to invoke the ShippingService
. Note that we can only get two of the arguments from the ShippingRequestMessage
: Customer
and Item[]
. The supporting documentation, which could be something like a Microsoft Word or Excel document, is an attachment to the ShippingRequestMessage
. Attachments can be associated with any message within Mule.
<expression-transformer>
<return-argument evaluator="bean" expression="customer"/>
<return-argument evaluator="bean" expression="shippingItems"/>
<return-argument evaluator="attachment" expression="supportingDocs" required="false"/>
</expression-transformer>
Here we execute three separate expressions to obtain the three arguments required to invoke the ShippingService.makeShippingRequest()
method. The first two expressions use the bean
evaluator to extract objects from the message. The last argument uses the attachment
evaluator to obtain a single attachment. Note that supportDocuments
can be null, so we set required="false"
on the return argument.
Message Properties Transformer
The <message-properties-transformer>
allows you to add, remove, or rename properties dynamically or statically on the current message. For example:
<message-properties-transformer>
<add-message-property key="GUID" value="#[string:#[xpath:/msg/header/ID]-#[xpath:/msg/body/@ref]]"/>
</message-properties-transformer>
The above expressions extract the <ID>
element value and the ref
attribute on the <body>
element, setting the result as a message property named GUID
.
XSLT Transformer
The XSLT transformer processes the XML payload of the message through XSLT. Using expressions, you can inject information about the current message into the XSLT as a parameter. For example:
<mulexml:xslt-transformer name="xslt" xslFile="./conf/xsl/cd-listing.xsl">
<mulexml:context-property key="title" value="#[header:ListTitle]"/>
<mulexml:context-property key="rating" value="#[header:ListRating]"/>
</mulexml:xslt-transformer>
When executed, the headers ListTitle
and ListRating
from the current message are added to the XSLT context as parameters called title
and rating
, respectively. You can reference these parameters inside the XSLT using the <xsl:param>
element:
<xsl:param name="title"/>
<xsl:param name="rating"/>
Using Expression Filters
Expression filters can be used in content-based routing to assert statements on the current message and route the message accordingly. Expression filters work in the same way as other types of Mule filters and have the same expression attributes as listed above. The expression on the filter must evaluate to true or false. For example:
<expression-filter evaluator="header" expression="my-header!=null"/>
As usual, you can use AND, OR, and NOT filters to combine expressions.
<and-filter>
<expression-filter evaluator="header" expression="origin-country=USA"/>
<expression-filter evaluator="groovy" expression="payload.purchase.amount > 10000"/>
</and-filter>
Note that expression filters support a sub-set of all expression evaluators, because filters should only evaluate against the current message. For example, there is no point in using a function
expression on a filter. The supported expression evaluators are: bean, custom, exception-type, groovy, header, jxpath, ognl, payload-type, regex, wildcard, and xpath. For more information on expression evaluators, see Expressions Configuration Reference.
For more information on filters, see Using Filters.
Using Expression Routers
Expression routers use expressions to determine where to route a message. Usually, outbound routers will support expressions. This section describes each of the Mule routers that support expressions. For more information on routers, see Using Message Routers.
Expression Recipient List Router
The <expression-recipient-list>
router will evaluate an expression on the current message to obtain a list of one or more recipients to send the current message. Following is an example of an XML message:
<message>
<header>
<routing-slip>
<recipient>http://mycompany.com/service1</recipient>
<recipient>http://mycompany.com/service2</recipient>
</routing-slip>
</header>
<body>
...
<body>
</message>
The following router configuration extracts recipients from this message. This type of routing is commonly referred to as content-based routing.
<outbound>
<expression-recipient-list-router evaluator="xpath" expression="/message/header/routing-slip/recipient" />
</outbound>
Best Practice This example uses physical addresses for endpoints in the message. In a real production scenario, you would use logical endpoint names that map to physical endpoint addresses. These can be configured in your Mule configuration file or in a centralized registry. |
Expression Splitter Router
The <expression-splitter-router>
can be used to route different parts of the current message to different destinations. Let’s say our current message is a FruitBowl
that contains different fruit that should be delivered to different places.
FruitBowl fruitBowl = new FruitBowl();
fruitBowl.addFruit(new Orange());
fruitBowl.addFruit(new Apple());
fruitBowl.addFruit(new Banana());
fruitBowl.addFruit(new Banana());
Now we have a FruitBowl
containing an apple, an orange, and two bananas. When Mule receives this object, we want to route the fruit to different locations: the AppleService, BananaService, and OrangeService.
<service name="Distributor">
<inbound>
<jms:inbound-endpoint queue="distributor.queue"/>
</inbound>
<outbound>
<!-- FruitBowl.getFruit() List -->
<expression-splitter-router evaluator="bean" expression="fruit">
<vm:outbound-endpoint path="apple.service.queue">
<payload-type-filter expectedType="org.mule.tck.testmodels.fruit.Apple"/>
</vm:outbound-endpoint>
<vm:outbound-endpoint path="banana.service.queue">
<payload-type-filter expectedType="org.mule.tck.testmodels.fruit.Banana"/>
</vm:outbound-endpoint>
<vm:outbound-endpoint path="orange.service.queue">
<payload-type-filter expectedType="org.mule.tck.testmodels.fruit.Orange"/>
</vm:outbound-endpoint>
</expression-splitter-router>
</outbound>
</service>
Notice that each of our outbound endpoints has a filter defined. This allows the splitter router to validate that the right object is routed to the right service. In this example, the AppleService and OrangeService will receive one request (fruit object) each and the BananaService will receive two. If the filters were not defined, the splitter router would send each object to the next endpoint in the list in a round robin fashion.
To read more about configuring expressions, see Expressions Configuration Reference.