Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

(Data)Weaving Expressions In Java

DZone's Guide to

(Data)Weaving Expressions In Java

Follow along with this guide to see how Dataweave and Java and combine to allow you transform your data with ease.

· Java Zone
Free Resource

Just released, a free O’Reilly book on Reactive Microsystems: The Evolution of Microservices at Scale. Brought to you in partnership with Lightbend.

I previously wrote an article called Weaving it with Dataweave expressions in the MuleSoft blog, which explains the powerful Dataweave expression function dw() and its implementation outside a Dataweave Transform Message component.

Dataweave has the ability to transform a message payload from one form to another and in any kind of format (XML, CSV, JSON, Pojos, Maps, etc).

As we have already seen, to execute a Dataweave expression outside a Dataweave Transform Message component, we need to put the expression inside the dw() function, enclosed in “quotation marks”, wrapped within an MEL expression #[ ].

The expression can be put into any transformer component, like a Set Payload transformer or an Expression transformer component, which is a pretty useful trick. It can quickly query data and use it to log information from payloads, route data to another flow (using the lookup function), or use it for quick payload transformation.

But what about using the dw() function in a Java component within a Mule application? The next thing that comes to mind is executing this function within a MEL expression with a Java class.

Here, in this article, we will demonstrate how to do just that.

Use Case

We will take the same example to transform an input JSON payload into an XML output payload with the Dataweave expression running in a Java class.

Let’s consider the following JSON input payload to be transformed into the XML payload:

Image title

So, as we have already seen in my older post Weaving it with Dataweave expressions, we can use the following Dataweave expression in an Expression transformer component and transform the output into our desired XML:

Image title

#[dw("{'root':{'myId':payload.id,'myName':payload.name,'mydescription':payload.description}}","application/xml")]


Before we proceed further, let’s have a quick recap on the format of the dw() function of Dataweave:

#[dw(“<Dataweave script>”, “<Output Mime type>”)]

The first parameter in this function is the Dataweave script that we use in our Dataweave component, and the second parameter is the output type of the payload, which we've designated as application/xml.

This time, we are going to execute this expression in a Java class to get our XML output.

Executing in Java

Mule has a Java Component, which is responsible for running all Java classes in a Mule application:

Image title

So, to do this, we need to design our Mule flow as follows:

Image title

Here we have placed the Java Component after the HTTP listener, which will take the input and execute the expression to transform into the XML payload and produce the output.

Our Mule flow configuration will be as follows:

<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>

 <flow name="DataweaveExpressionFlow">
   <http:listener config-ref="HTTP_Listener_Configuration" path="/transform" doc:name="HTTP"/>
   <component class="com.utils.ExpressionTestInJava" doc:name="Java"/>
 </flow>


So, here we can see our Mule flow contain the Java Component referring to a Java class which is below:-

package com.utils;
import org.mule.DefaultMuleEvent;
import org.mule.api.MuleEvent;
import org.mule.api.MuleEventContext;
import org.mule.api.lifecycle.Callable;
public class ExpressionTestInJava implements Callable {
       @Override
       public Object onCall(MuleEventContext eventContext) throws Exception {
              String expressionStr = "#[dw(\" {'root':{'myId':payload.id,'myName':payload.name,'mydescription':payload.description}}\",\"application/xml\")]";
              MuleEvent muleEvent = new DefaultMuleEvent(eventContext.getMessage(), eventContext.getExchangePattern(),eventContext.getFlowConstruct());
              Object response = eventContext.getMuleContext().getExpressionManager().evaluate(expressionStr, muleEvent);
              return response;
       }
}


The expression in a Java class is evaluated with the org.mule.api.expression. ExpressionManagerevaluate() function. The expression should be a single expression definition with or without enclosing braces.

If you see the Java class, you will find few characters like double quotes are capped with \”.

Testing our Application

So, let's run our application now and test the flow using a REST Client tool or Postman and hit the URL, http://localhost:8081/transform, with a POST method as follows:

Image title


You can see that we are posting our JSON payload as an input, and this is what we get above. A response in XML!

Externalizing the Script

A common question that comes to mind is, "Can we externalize the Dataweave expression script?"

Of course.

One way we can do it is by putting it in a properties file, such as mule-app.properties, with a key. We can retrieve the value in the Java class by simply using a System.getProperty("Key name") function.

Simple, isn’t it?

So, we can modify our Java class as follows:

package com.utils;
import org.mule.DefaultMuleEvent;
import org.mule.api.MuleEvent;
import org.mule.api.MuleEventContext;
import org.mule.api.lifecycle.Callable;
public class ExpressionTestInJava implements Callable {
       @Override
       public Object onCall(MuleEventContext eventContext) throws Exception {
              String expressionStr = "#[dw(\""+System.getProperty("dw.expression")+"\",\""+System.getProperty("mimeType")+"\")]";
              MuleEvent muleEvent = new DefaultMuleEvent(eventContext.getMessage(), eventContext.getExchangePattern(),eventContext.getFlowConstruct());
              Object response = eventContext.getMuleContext().getExpressionManager().evaluate(expressionStr, muleEvent);
              return response;
       }
}


And we will place the following key-value in mule-app.properties file:-

dw.expression={'root':{'myId':payload.id,'myName':payload.name,'mydescription':payload.description}}
mimeType=application/xml

We have separated the expression and mimeType separately in the properties file to make it easy and independent.


Testing Our Application Again

Now, if we run our application again to test the flow using a REST Client tool or Postman and hit the URL, http://localhost:8081/transform, with a POST method with the same JSON input, we get the following:

Image title

As you can see, we will get the same result without any problem.

Conclusion

As we have seen, it's easy to use different components, starting from a logger component, a Set Payload transformer or Expression transformer component, and even a Java component. The Dataweave expression fits everywhere easily and helps us to quickly transform and perform the Dataweave Transform Message Component function in other components.

I hope you liked this post, and you can provide your experience with this Dataweave expression below as a comment.

Strategies and techniques for building scalable and resilient microservices to refactor a monolithic application step-by-step, a free O'Reilly book. Brought to you in partnership with Lightbend.

Topics:
dataweave ,json ,java ,data transformation

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}