Example setup
<api name="testAPI" context="/transform"> <resource methods="POST" uri-template="/example1"> <inSequence> <log level="full"/> <respond/> </inSequence> <outSequence/> <faultSequence/> </resource> <resource methods="POST" uri-template="/example2"> <inSequence> <property name="messageType" value="application/json" scope="axis2" type="STRING"/> <log level="full"/> <respond/> </inSequence> <outSequence/> <faultSequence/> </resource> </api> |
Compared to the previous blog where I just sent a JSON object into the API I will instead start with a JSON array. The JSON array can be identified by the opening and closing brackets [ ] I’ve added several several jsonObjects to it.
Example request 1
{ "Objects":[{ "testObject": { "testValue1": "value", "testValue2": "value" }, "testObject2": { "testValue1": "value", "testValue2": "value" }, "testObject3": { "testValue1": "value", "testValue2": "value" } }] } |
When I send a POST request of this to the API and check out the logs I find the below message. Just like before the ESB creates a jsonObject around the message to designate the surrounding jsonObject but there is no special element for the JSON array.
Example 1 during mediation inside the product
<jsonObject> <Objects> <testObject> <testValue1>value</testValue1> <testValue2>value</testValue2> </testObject> <testObject2> <testValue1>value</testValue1> <testValue2>value</testValue2> </testObject2> <testObject3> <testValue1>value</testValue1> <testValue2>value</testValue2> </testObject3> </Objects> </jsonObject> |
The result we get back is exactly the same JSON message as the input. So the bus manages to retain knowledge of it being an array even without a special xml element around it.
Next we will try the same going from xml to json through the product.
As this input message I will use the xml message I showed above, which I took directly from the wso2carbon.log and send it to the example 2 api url “/transform/example2”.
Example request 2
<jsonObject> <Objects> <testObject> <testValue1>value</testValue1> <testValue2>value</testValue2> </testObject> <testObject2> <testValue1>value</testValue1> <testValue2>value</testValue2> </testObject2> <testObject3> <testValue1>value</testValue1> <testValue2>value</testValue2> </testObject3> </Objects> </jsonObject> |
Example 2 output message
{ "Objects": { "testObject": { "testValue1": "value", "testValue2": "value" }, "testObject2": { "testValue1": "value", "testValue2": "value" }, "testObject3": { "testValue1": "value", "testValue2": "value" } } } |
As you can see the return message is missing the jsonArray and instead just turned into an object. This is because the original input message has no indication of any of the elements needing to be an array once it has been converted to JSON.
So, how can you make sure the received xml message is turned into the json result you’re looking for? The default JSON message formatter inside the ESB supports the <?xml-multiple?> tag, you can use this to designate the next element after to be an array once it’s been converted to JSON. If the origin system that sends the message is not able to add this element to the message it will have to be added to the message context during mediation on the bus.
For this we will add an extra resource call to the API with an Example3 API url /example3 and use the input from the example 2 request.