The WSO2ESB comes with several JSON MessageFormatters and MessageBuilders. These different formatter/builder pairs allow you to adhere to different JSON formatting standards. ESB 5.0.0 comes standard with the .JsonStreamFormatter and JsonStreamBuilder enabled, and allows you to use the JsonFormatter and JsonBuilder. The big difference between the streaming and the non streaming variant: the streaming variant leaves the JSON untouched as long as possible. When the response from the backend is not transformed, it is sent ‘as is’ to the client invoking the service.
(For backwards compatibility, a few other JSON Formatters and Builders are still included. These are left out of scope in this blog, for more info see https://docs.wso2.com/display/ESB500/JSON+Support )
The default behavior of both the JsonStreamFormatter and JsonFormatter is to ‘Allows primitive types in the JSON output in XML to JSON transformations’. This mean any content that is a valid number will be represented in the JSON message as a number:
If you don’t allow primitive types in the JSON output one can simply disable it by adding ‘synapse.commons.json.output.autoPrimitive = false’ to the configuration file [ESB_HOME]/repository/conf/synapse.properties.
However, this setting:
- is a global setting, so it applies for all services (proxies/api’s)
- can’t be overwritten by property mediator, nor by any custom mediator.
What can one do when you want the ESB to act differently on different services or even within a service? I’ve done projects, in which I had to create JSON messages in which some fields always must be formatted as a String, also when its value is a number where other fields must be formatted as a number. This is not possible by the out-of-the-box configuration of the ESB.
According to the documentation you should be able to specify a regular expression which turns off the auto primitive for a single object:
synapse.commons.json.output.disableAutoPrimitive.regexUnfortunately, this seems not to be working in version 5.0.0.
The WSO2ESB is an open source product, which allows us to go through the code step by step in a remote debugging session, showing what is happening under the hood. It also shows how the standard mediators work … Both helped me a lot while writing my JsonFormatter mediator.
Inside the JsonFormatter mediator
All the magic happens in just three methods:
mediateThe starting point of every mediator is the mediate method which is called by the ESB when the mediator is invoked. Inside this method the JSON payload is retrieved from the message, a JSONObject or JSONArray is created. This JSONObject or JSAONArray is processed by the two other methods:
Inside the fixJsonArray method, all objects (JSONObjects and JSONArrays) in a JSONArray are processed:
Inside the fixJSONObject method, the real magic happens:WHEN the JSONObject has a property ‘@force’ with the value ‘string’ AND it has a property ‘$’ with a value THEN this method returns a JSONObject whose value is forced to be a String. WHEN the JSONObject has a property ‘@force’ with the value ‘string’ AND it has a property ‘$’ without a value THEN a JSONObeject.NULL is returned.OTHERWISE the JSONObject is more or less returned ‘as is’.
JsonFormatter in action
Let’s fake a real service by a proxy with a payload mediator, forcing the result to be JSON by setting the messageType:
When we invoke this ‘service’ it returns the reference and description as a number:
Copy the built jar into the directory
repository/components/dropins, restart the ESB.
force=”string” attribute to the elements reference and description and add the jsonFormatter mediator:
Now we see a different JSON response. Both the reference and description are formatted as a string.
If you have any questions about this blogpost contact us via the comments section of this blog. For more View also our WSO2 Tutorials, webinars or white papers for more technical information. Need support? We do deliver WSO2 Product Support, WSO2 Development Support, WSO2 Operational Support and WSO2 Training Programs.