WSO2 - Mapping XML to Java Using Smooks Mediator

In this post we will show how we can use smooks mediator to transform a XML Message into Java Objects using Smooks mediator in WSO2 Enterprise Integrator.

In this example we will map a XML Message into a list of HashMap.

Smooks Config File

For this example we are going to parse a message like below:

<order>
  <order-items>
      <order-item>
          <product>111</product>
          <quantity>2</quantity>
          <price>8.90</price>
      </order-item>
      <order-item>
          <product>222</product>
          <quantity>7</quantity>
          <price>5.20</price>
      </order-item>
  </order-items>
</order>

Now let us see the Smooks Config file:

<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd">

    <!--
        The "xml-to-java-virtual" sample config is the same as that of the "xml-to-java" sample accept for the fact that
        xml-to-java-virtual uses HashMaps (virtual) in place of a fully defined (physical) object model.
    -->
    <!--
    Create an ArrayList bean instance when we visit the start of the <order> element.
    This bean is wired into the "order" bean.
    -->
    <jb:bean beanId="orderItems" class="java.util.ArrayList" createOnElement="order">
        <jb:wiring beanIdRef="orderItem" />
    </jb:bean>

    <!--
    Create an "java.util.HashMap" bean instance when we visit the start of the <order-item> element.
    This bean is wired into the "orderItems" ArrayList bean.
    -->
    <jb:bean beanId="orderItem" class="java.util.HashMap" createOnElement="order-item">
        <jb:value property="productId" decoder="Long" data="order-item/product" />
        <jb:value property="quantity" decoder="Integer" data="order-item/quantity" />
        <jb:value property="price" decoder="Double" data="order-item/price" />
    </jb:bean>

</smooks-resource-list>

This Smooks Config is mapping each order-item element into a HashMap instance. For each jb:value tag it will add a HashMap entry using the property attribute as key and the data attribute will refer to the XML tag that holds the value.

This Smooks configuration is exporting the XML mapping as a JavaResult. With a JavaResult bean we can get the beans created during the mapping using the value use in the beanId property.

ProxyService

Follow the code for the ProxyService that will use the Smooks Configuration.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
   name="TestProxy"
   startOnLoad="true"
   statistics="disable"
   trace="disable"
   transports="http,https">
<target>
  <inSequence>
     <log level="custom">
        <property name="STATUS" value="SmooksTest"/>
     </log>
     <!--
     Creating a Paylod for Testing
     -->
     <payloadFactory media-type="xml">
        <format>
           <order>
              <order-items>
                 <order-item>
                    <quantity>2</quantity>
                    <product>111</product>
                    <price>8.90</price>
                 </order-item>
                 <order-item>
                    <price>5.20</price>
                    <product>222</product>
                    <quantity>7</quantity>
                 </order-item>
              </order-items>
           </order>
        </format>
        <args/>
     </payloadFactory>

     <!--

      Invoking the Smooks Config file
      It is deployed as a local entry named Smooks-test

      The input Type is xml
      Output type is Java and we define the property name it will export the
      JavaResult object to.
     -->

     <smooks config-key="Smooks-test">
        <input type="xml"/>
        <output property="javaResult" type="java"/>
     </smooks>
     <log level="custom">
        <property name="STATUS" value="PROCESSED MSG**********"/>
     </log>
     <!--
      A Simple Script Mediator to use the JavaResult bean generated on
      the Smooks Transformation.
      We can refer to the beans generated using the getBean method of JavaResult object
     -->
     <script language="js">print(mc.getProperty('javaResult').getBean("orderItems"));</script>
  </inSequence>
  <outSequence/>
  <faultSequence/>
</target>
<description/>
</proxy>

Basically we are:

  1. Declaring a test payload using the payloadFactory mediator. This is the payload that the smooks mediator is going to process;
  2. We use the smooks mediator. We refer to the Smooks config file using the config-key attribute. In this case we are deploying the config file as a LocalEntry.
  3. The Input is XML. The Output we declare as java and we define the property name that the JavaResult generated in the transformation will be exported to.
  4. We use a script mediator to use the Java Object generated on the transformation.

If we invoke the proxy service in the TryIt tool we will see something like this in the console logs:

[2017-11-19 17:26:36,931] []  INFO - LogMediator STATUS = PROCESSED MSG**********
[{quantity=2, productId=111, price=8.9}, {quantity=7, productId=222, price=5.2}]

In the log we can see the toString output of the List of HashMaps.

We can also map the XML to a JavaBean instead of HashMaps. And we use those Java objects inside a custom mediator and apply some custom processing.

I hope you enjoyed.

See you in the next post!

comments powered by Disqus