Showing posts with label json. Show all posts
Showing posts with label json. Show all posts

Friday, April 29, 2022

Having fun with Jolt transformations

Jolt is a Java library which can be used to transform JSON to JSON (here). A Jolt transformation itself is also a JSON file. You can use it in products such as Apache NiFi and Apache Camel. In this blog post I'll describe my first experiences with Jolt transformations. 

For me personally Jolt transformations are not intuitive and not that powerful when for example compared to the capabilities of XSLT for transforming XML. It is available in Apache NiFi though and can be used without the 'execute code' permission, that is why I decided to use it to transform JSON files. I might misunderstand basic Jolt concepts which can cause suggested solutions to be overly complex or in other ways suboptimal.

Monday, April 25, 2022

Apache NiFi: JSON to SOAP

Apache NiFi is a powerful open source integration product. A challenge you might encounter when integrating systems is that one system can produce JSON messages and the other has a SOAP API available. In this blog post I'll show how you can use NiFi to convert JSON input to a SOAP service call. This involves abstracting an AVRO schema for the JSON, converting it to XML and transforming the XML to a SOAP message. 

In this example I'm using several publicly available websites. You should of course be careful. Do not copy/paste sensitive XML or JSON on these sites!

Thursday, January 27, 2022

Java: Validating JSON against an AVRO schema

AVRO schema are often used to serialize JSON data into a compact binary format in order to for example transport it efficiently over Kafka. When you want to validate your JSON against an AVRO schema in Java, you will encounter a challenge. The JSON which is required to allow validation against an AVRO schema from the Apache AVRO libraries is not standard JSON. It requires explicit typing of fields. Also when the validation fails, you will get errors like: "Expected start-union. Got VALUE_STRING" or "Expected start-union. Got VALUE_NUMBER_INT" without a specific object, line number or indication  of what is expected. Especially during development, this is insufficient.

In this blog post I'll describe a method (inspired by this) on how you can check your JSON against an AVRO schema and get usable validation results. First you generate Java classes of your AVRO schema using the Apache AVRO Maven plugin (which is configured differently than documented). Next you serialize a JSON object against these classes using libraries from the Jackson project. During serialization, you will get clear exceptions. See my sample code here.

Monday, January 24, 2022

Generating random JSON data from an AVRO schema in Java

Recently I was designing an AVRO schema and wanted to test how data would look like which conformed to this schema. I developed some Java code to generate sample data. This of course also has uses in more elaborate tests which require generation of random events. Because AVRO is not that specific, this is mainly useful to get an idea of the structure of a JSON which conforms to the definition. Here I'll describes a simple Java (17 but will also work on 11) based solution to do this.

Saturday, February 1, 2020

HTTP benchmarking using wrk. Parsing output to CSV or JSON using Python

wrk is a modern HTTP benchmarking tool. Using a simple CLI interface you can put simple load on HTTP services and determine latency, response times and the number of successfully processed requests. It has a LuaJIT scripting interface which provides extensibility. A distinguishing feature of wrk compared to for example ab (Apache Bench) is that it requires far less CPU at higher concurrency (it uses threads very efficiently). It does have less CLI features when compared to ab. You need to do scripting to achieve specific functionality. Also you need to compile wrk for yourself since no binaries are provided, which might be a barrier to people who are not used to compiling code.

Parsing the wrk output is a challenge. It would be nice to have a feature to output the results in the same units as CSV or JSON file. More people asked this question and the answer was: do some LuaJIT scripting to achieve that. Since I'm no Lua expert and to be honest, I don't have any people in my vicinity that are, I decided to parse the output using Python (my favorite language for data processing and visualization) and provide you with the code so you don't have to repeat this exercise.

You can see example Python code of this here.   

Monday, November 2, 2015

SOA Suite 12.2.1: A first look at end-to-end JSON support in SOA Composites

SOA Suite 12.2.1 introduces end-to-end JSON support in composites, support for JavaScript in BPEL and a JavaScript embedding activity. The REST-binding (which can be used by Service Bus, BPEL, BPM) can receive and send untyped JSON without the need to translate it to XML. In BPEL, JavaScript can be used as expression language in various activities and there is a JavaScript embedding activity available.

In this article I'll show some examples on what you can do with this end-to-end JSON support and give some examples on how to use JavaScript in your BPEL process.


Sunday, April 12, 2015

Combine version control (SVN) and issue management (JIRA) to improve traceability

Version control and bug tracking systems are found in almost every software development project. Both contain information on release content. In version control, it is usual (and a best practice) to supply an issue number when code is checked in. Also it allows identification of code which is in a release (by looking at release branches). Issue management allows providing metadata to issues such as the fix release and test status. This is usually what release management thinks is in a release.

In this article I will provide a simple example on how you can quickly add value to your software project by improving traceability. This is done by combining the information from version control (SVN) and issue management (JIRA) to generate release notes and enforcing some version control rules.

To allow this to work, certain rules need to be adhered to.
  • code is committed using a commit message or tag which allows linking of code to issue or change
  • it should be possible to identify the code which is part of a release from version control
  • the bug tracking system should allow a selection of issues per release

Thursday, June 26, 2014

SOA Suite 12c: Introducing the REST Adapter

The REST Adapter is an important new feature of Oracle SOA Suite 12c. This new adapter allows easy calling/exposing of RESTful services (see http://javaoraclesoa.blogspot.nl/2014/05/what-is-rest.html for an introduction to REST) based on a WADL or configured manually. Not only does Oracle introduce the REST Adapter, but JSON support is also added in SOA Suite 12c. These features will greatly increase the integration options and flexibility of Oracle SOA Suite. In this blog I'll describe how a RESTful service can be called by using the REST adapter. Exposing a RESTful service will be described in a later blog.

SOA Suite 12c: RESTAdapter: Exposing and testing RESTful services

In my previous two blog posts I have described REST (here) and how the new Oracle SOA Suite 12c REST adapter can be used to call RESTful services (here). I recommend those articles to be read first if you're new to REST in order to better understand this article.

The newly introduced Oracle SOA Suite 12c REST adapter provides options for calling RESTful services but it can also be used to expose RESTful services. These exposed services can use XML or JSON as message exchange format. As described in the previous blog post, JSON support is implemented by implementing NXSD (Native Format Builder schema definition files, more information here) to describe the JSON message and make the transformation to and from XML possible. This XML can then be used as usual by the different components in a composite.

Monday, May 12, 2014

MockServer: Easy mocking of HTTP(S) services (e.g. SOAP or JSON)

Testing services as an atomic entity can be difficult. Especially if these services are part of a call chain or call other services. Often in such cases mock services are developed to reduce test dependencies and exclude services which are not interesting to the specific test case. For example, I'm testing service A. Service A calls service B. I'm not interested in service B (or service B is maintained by another department on which I don't want to depend). I would mock service B when testing service A in this case. There are several methods to create mock services. These methods however are mostly not easily usable by testers since they require developing/coding mock services. Testers would benefit from being able to create their own mock services in order to create different tests for a specific service.

In this blog post I provide a brief introduction and describe some features of MockServer. An open source product which can be used to mock services. For a more detailed article (with more examples) you can look at the following written by my colleague Robert van Mölken: http://technology.amis.nl/2014/03/06/functional-boundary-testing-of-a-service-based-environment-using-mockserver/

The below image was taken from http://www.mock-server.com/

Tuesday, January 8, 2013

A JSON HelloWorld BPEL process

Introduction

In several previous posts I've discussed various issues encountered when trying to build a HelloWorld JSON BPEL process. Such as;

Differences between JSON and XML and an example of a simple conversion
- http://javaoraclesoa.blogspot.nl/2012/07/webinterface-restjson-vs-middleware.html

Receiving JSON requests in BPEL by using the SocketAdapter
- http://javaoraclesoa.blogspot.nl/2012/12/receiving-json-requests-in-oracle-bpel.html

A reusable solution for transforming from JSON to XML and back again in order to avoid a mapping layer.
- http://javaoraclesoa.blogspot.nl/2012/12/a-reusable-solution-for-conversion.html

In this post I'm expanding on the above posts and putting the things I've created together to provide a working example of how BPEL and Json can interoperate with each other in a reusable way. In this example I'll show how JSON can be received in BPEL, can be transformed to XML and be edited in BPEL (using XSLT). The result is then transformed back to JSON and returned to the requester.

Implementation

Receiving Json

A JSON message is received by using the SocketAdapter. As mentioned in a previous post, the request and response can be parsed by using XSLT functions. This however is difficult and not safe. For example, the inbound request contains HTTP headers. These headers tell things about the HTTP body. I would have to use XPath functions in order to create an HTTP interpreter. This did not seem the way to go (as concluded before) so I've used a different approach. I've a custom Java class which used Apache HttpComponents (http://hc.apache.org/) to provide the HTTP implementation and parsing of the incoming request. The code can be downloaded at the end of this post.

Editing JSON in BPEL

I've used my previously created Webservice to convert Json to XML and back to Json as described on; http://javaoraclesoa.blogspot.nl/2012/12/a-reusable-solution-for-conversion.html. This way I could do XSLT transformations on XML describing JSON messages and later go back to JSON again when sending the reply.

The result

First I've tested my service by using SOAP UI. The result can be seen below;


Next I looked up my BPEL process in the Fusion Middleware Console


This way you can exactly see what has happened to the JSON code. First it is received. Then it is translated to XML. Next XSLT is used to transform the resulting XML. This resulting XML is transformed back to JSON and the result is replied to the caller.

I've also tried opening the service in a webbrowser with the expected result (a normal GET HTTP request doesn't contain a body);


Performance

Sometimes stories are told about poor performance of BPEL and the large overhead incurred by using SOAP and XML. Since I was curious about this (claims should of course be tested!) I've done a small measure on my HelloWorldJSONBPEL service;


As can be seen in the screenshot above, 68ms is the average response time under high load. This was however not an optimized process on development audit logging running on a server in a virtual machine on my desktop. This performance does not surprise or worry me, I can however imagine that a plain Java servlet receiving/replying JSON is faster. I've not created such a servlet to test this. In plain Java however you won't be able to use some of the advanced monitoring tools of the SOA Suite.

Conclusion

Reusable interoperability between JSON and XML is possible. It requires however some work and figuring out. Also if you want to use different endpoints on the same port, some routing is required based on the status line in the HttpRequest. Security is also an issue. If you want to secure the SocketAdapter port you can implement HTTP classes which support authentication mechanisms or you can use for example a service bus to provide this functionality. It requires some tweaking though.

Something I'm not happy about is the sending of the HTTP response. I'm still manually providing HTTP header lines. This should not be needed when working with the Apache HttpComponents.

An expectation is that the 12c release of the SOA Suite which will be released somewhere half 2013 will contain better JSON support. Also see http://technology.amis.nl/wp-content/uploads/2012/11/AMIS-Whitepaper-OOW-2012.pdf. This would render custom implementations obsolete if the implementation provided in that release is sufficient.

You can download the complete sample project here; https://dl.dropbox.com/u/6693935/blog/JsonExample.zip

Friday, December 21, 2012

A reusable solution for the conversion between JSON and XML

Two popular information exchange notations/languages are Json and XML. In order to provide interoperability between frameworks using different mechanisms of information exchange, a conversion between the two is required. There is however not a strict way to provide a conversion; http://jackson-users.ning.com/forum/topics/xml-to-json-conversion-using.

I've seen several solutions in practice to provide the conversion for example;
- using a service bus to make the translation from XML to JSON and the other way around
- using a Java HttpServlet with JAX-B to provide a mapping

There are also other solutions such as embedding a Java JSON client in the BPEL code; http://technology.amis.nl/2009/12/15/the-oracle-soa-suite-11g-httpbinding-or-another-way-to-call-restful-services-from-soa-composite-applications/

Those solutions however require work per service and are thus not very reusable. When the service landscape consists of a lot of services, this creates an extra mapping layer which needs maintenance.

A reusable solution

JSON is structured (http://www.w3resource.com/JSON/structures.php; objects, arrays and values). The conversion from JSON to XML (and the other way around) can be fixed and a single message definition (XSD) can be provided.

In order to provide a single reusable conversion from JSON to XML and XML to JSON, an XML schema is required which is capable of containing JSON structures. Luckily, the internet is a big place and I could find several examples of such XSD's such as; http://xml.calldei.com/JsonXML. This way, only a single set of JAX-B classes can be used and only two pieces of mapping code to make the transformation work. If you have a different Json message (sending or receiving), it can be mapped to the same XML so no additional programming is required for individual services.

Based on the schema, I used JAX-B to generate Java classes. Then I used Jackson Json processor to create Json (http://jackson.codehaus.org/). I wrote a mapping from the JAX-B objects to JsonNodes and the other way around. Next I exposed this as a webservice so it could for example easily be called from BPEL.

Implementation

I managed to create a reversible transformation from Json to a fixed Xml schema and the other way around. Also I've provided a test method to check if the conversion works (the following two conversions lead to the original result; JSON -> XML -> JSON) for specific Json messages. Keep in mind that JSON strings need to be enclosed in ". This allows Json to be used in XML based systems for request and response handling. Also, because the schema is fixed, it can easily be used in XML based systems to build JSON messages.

I've used recursive methods to walk the XML and JSON trees respectively and convert them to the other type. The code is not thoroughly tested so should not be used carelessly in production environments.

The example webservice can be downloaded here (JDeveloper 11.1.1.6 project); https://dl.dropbox.com/u/6693935/blog/JsonXml.zip

Conclusion

When combined the above with the SocketAdapter functionality as described in http://javaoraclesoa.blogspot.nl/2012/12/receiving-json-requests-in-oracle-bpel.html the Hello World JSON BPEL process is not farfetched anymore. I didn't manage to complete this yet however. I've spend some time on getting the SocketAdapter to work with the XSL (request/reply) transformations. I came to the conclusion that usage of the socket XSLT functions is hard. One of the issues I encountered is when the server should start sending back a reply. Also getting the body from the HTTP message could be better programmed out in Java (using the Content-Length HTTP header to obtain the correct body).

The other way around; converting an XML to a fixed Json message and back again to obtain the original result, is more difficult. An example of a method of converting XML to Json can be found on; http://javaoraclesoa.blogspot.nl/2012/07/webinterface-restjson-vs-middleware.html. This transformation is however not reversible.

Friday, December 7, 2012

Receiving JSON requests in Oracle BPEL by using the SocketAdapter


Some frameworks prefer the use of JSON, such as webinterface frameworks, GIS frameworks or mobile app frameworks. In order to integrate and provide for example service orchestration, Oracle SOA Suite can be used. Oracle SOA Suite however does not have a JSONAdapter in the current release.

Using the HTTPAdapter is not an option to provide JSON support. The Oracle HTTPAdapter does not support receiving and sending JSON (only XML). It can however be used to send a HTTP GET request with parameters which is how REST services are often called. See for example; http://shrikworld.blogspot.nl/2011/04/http-adapter-in-soa-11g.html

The SocketAdapter however does not have the XML limitations of the HTTPAdapter. In this post I describe how the SocketAdapter can be used to receive a JSON message from an HTTP Post request.

Implementation

SocketAdapter

To use the  SocketAdapter for this usecase requires some parsing of the HTTP communication which is usually abstracted. It is possible to use XSLT or a custom Java class to parse the request received from the adapter and transform it to XML (http://docs.oracle.com/cd/E21764_01/integration.1111/e10231/adptr_sock.htm#BABHECAG). I decided to try the XSLT option.

I downloaded an example from; http://java.net/projects/oraclesoasuite11g/pages/SocketAdapters

In this example I needed to change the following to get it to work;
- update adf-config.xml with the correct path of the jdeveloper/integration folder
- make sure bpm-infra.jar is in the classpath of the server

Based on the configuration of the SocketAdapter connection factory I tried connecting to port 12110 with telnet.

In the logfile I saw the following;

- Socket Adapter ClientProcessor:run() Error occured in processing client request
- Socket Stylesheet Parsing Error.
Error while trying to parse the stylesheet.
Please ensure that that the stylesheet exists and is configured properly. Please cross check the extension functions. Contact Oracle support if error is not fixable. 


This was as expected since I didn't provide the correct test message.

When I opened in my browser; http://localhost:12110 it did work however. I noticed the input was;

0.9,*/*

I wondered where this came from. I created a custom Java socket listener based on http://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html and http://zerioh.tripod.com/ressources/sockets.html and did the request on the listener. The result was;

client>GET / HTTP/1.1
client>Host: localhost:2004
client>User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0
client>Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
client>Accept-Language: en-US,en;q=0.5
client>Accept-Encoding: gzip, deflate
client>Connection: keep-alive


The request.xsl from the example was as followed;

<?xml version="1.0" encoding="windows-1252" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ora="http://www.oracle.com/XSL/Transform/java/"
                xmlns:socket="http://www.oracle.com/XSL/Transform/java/oracle.tip.adapter.socket.ProtocolTranslator"
                xmlns="http://xmlns.oracle.com/HelloWorld">
 <!-- Root template -->
 <xsl:template match="//input">
  <!-- Input coming from the browser would look like
  GET /input=sagar; HTTP/1.1.
  dummy variable to read the input= text -->
  <xsl:variable name="variable1"
                select="socket:socketRead('terminated', 'terminatedBy==')"/>

               
  <!-- Read the input string terminated by ;and build the input xml -->
  <HelloWorldProcessRequest>
   <input>
    <xsl:value-of select="socket:socketRead('terminated', 'terminatedBy=;')"/>
   </input>
  </HelloWorldProcessRequest>
 </xsl:template>
</xsl:stylesheet>



The SocketAdapter took the part from the first = sign to the first ; after that. This was confirmed by looking at the log set to trace level.

When trying again with telnet with the input;
input=Maarten;

It worked and I got an instance of my process. I was however not yet able to receive JSON from a HTTP POST request. First I needed an example request;

POST /request HTTP/1.1
Accept: application/jsonrequest
Content-Length: 123
Content-Type: application/jsonrequest
Host: localhost

{"user":"test","var":7,"t":"something","stuff":123}


I needed to extract everything after the first empty line (I'm not sure yet if this is always the case in HTTP messages!) to the end of the message. This way if the JSON message was multiline, it would also work. To do that I needed to understand the XPath function socket:socketRead used in the XSLT transformation used by the SocketAdapter when receiving the message

I found the following (http://docs.oracle.com/cd/E21764_01/integration.1111/e10231/adptr_sock.htm#BABHECAG);

"By using StyleReader, which is exposed by the NXSD framework, to read and write from the socket stream using the following methods: socketRead(nxsdStyle:String, nxsdStyleAttributes:String):String"

I remembered from the Native Format Builder (which also uses the NXSD framework) some codes I could use in the terminatedBy clause. The resulting XSLT for my usecase was;

<?xml version="1.0" encoding="windows-1252" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ora="http://www.oracle.com/XSL/Transform/java/"
                xmlns:socket="http://www.oracle.com/XSL/Transform/java/oracle.tip.adapter.socket.ProtocolTranslator"
                xmlns="http://xmlns.oracle.com/HelloWorld">
 <!-- Root template -->
 <xsl:template match="//input">
  <!-- Input coming from the browser would look like
  GET /input=sagar; HTTP/1.1.
  dummy variable to read the input= text -->
  <xsl:variable name="variable1"
                select="socket:socketRead('terminated', 'terminatedBy=${eol}${eol}')"/>

              
  <!-- Read the input string terminated by ;and build the input xml -->
  <HelloWorldProcessRequest>
   <input>
    <xsl:value-of select="socket:socketRead('terminated', 'terminatedBy=${eof}')"/>
   </input>
  </HelloWorldProcessRequest>
 </xsl:template>
</xsl:stylesheet>


With this XSLT to parse the request I could obtain the JSON String from a HTTP POST request. This is the first step in creating a BPEL JSON HelloWorld service.

JsonPath

The parsing or querying of a JSON String can be done in several ways such as using the JsonPath (http://code.google.com/p/json-path/). Below is code for an example webservice which can be used.

package ms.testapp.soa.utils;

import com.jayway.jsonpath.JsonPath;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService
public class JsonPathUtils {
   
    @WebResult(name = "result")
    public String ExecuteJsonPath(@WebParam(name = "jsonstring") String jsonstring, @WebParam(name = "jsonpath")String jsonpath) {
        String result = JsonPath.read(jsonstring, jsonpath).toString();
        return result;
    }
   
    public JsonPathUtils() {
        super();
    }
/*   
    public static void main(String[] args) {
        JsonPathUtils myPath = new JsonPathUtils();
        System.out.println(myPath.ExecuteJsonPath("{ \"store\": {\n" +
        "    \"book\": [ \n" +
        "      { \"category\": \"reference\",\n" +
        "        \"author\": \"Nigel Rees\",\n" +
        "        \"title\": \"Sayings of the Century\",\n" +
        "        \"price\": 8.95\n" +
        "      },\n" +
        "      { \"category\": \"fiction\",\n" +
        "        \"author\": \"Evelyn Waugh\",\n" +
        "        \"title\": \"Sword of Honour\",\n" +
        "        \"price\": 12.99,\n" +
        "        \"isbn\": \"0-553-21311-3\"\n" +
        "      }\n" +
        "    ],\n" +
        "    \"bicycle\": {\n" +
        "      \"color\": \"red\",\n" +
        "      \"price\": 19.95\n" +
        "    }\n" +
        "  }\n" +
        "}", "$.store.book[1].author"));
    }
*/
}


Conclusion

I haven't finished the HelloWorld BPEL JSON service implementation yet. What I've found however is that it requires some work to get relatively simple functionality.

Not only does it require some work, but to make the code reusuable is also a challenge. You will need routing mechanisms which sounds a lot like where the OSB is really good at.
JSON is often used when performance is important. JSON messages can be smaller then XML messages and a strict message or interface definition (such as for XML XSD/WSDL) is not a requirement. Also the (Java) frameworks required to work with JSON are often relatively easy to implement making quick development possible. When using the above solution, several components are used which cause additional overhead (such as the SocketAdapter and XSLT transformations). This is expensive when considering there can be a relatively light and easy implementation by using the OSB or custom Java code per integration.

Friday, July 13, 2012

Webinterface REST/JSON vs Middleware SOAP/XML

Introduction

JavaScript

Webdevelopers use a lot of JavaScript on the clientside. There are things which JavaScript is good at and there are things you're better of not doing in JavaScript. JSON and REST are often used by JavaScript developers and XML and SOAP are shunned.

JSON

JSON (see http://www.json.org/), the JavaScript Object Notation, is an easy lightweight notation which can be used to transfer JavaScript objects; objects can be transported as strings. JSON is a lot easier for JavaScript then for example XML. JSON has some query languages (such as XQuery / XPATH for XML) which are still work in progress but seem to work to some extend; http://stackoverflow.com/questions/777455/is-there-a-query-language-for-json. For Java there are libraries available to make working with JSON more easy (such as JSON-lib and Jackson JSON).

REST

Since webinterfaces nowadays often require asynchronous interaction with the server to for example validate values in forms without requiring a submit of the entire form, services on the server are often deployed.

For service interaction, JavaScript can easily do HTTP POST and GET requests but it is harder to create entire SOAP messages. An example on how asynchronous HTTP requests can be done from JavaScript; http://rest.elkstein.org/2008/02/using-rest-in-javascript.html

REST services (http://en.wikipedia.org/wiki/Representational_state_transfer) are an alternative to SOAP services. REST services often do not have an interface defined (WSDL and WADL are disputable for REST services); there is often less strict message exchange (if you want to validate messages or throw exceptions, you have to do it yourself, they are application specific and not inherent to the protocol). For the sake of quick (webinterface) development, less strict standards can be a choice.

Oracle SOA and webinterfaces

This is an Oracle SOA / Java blog, so where do those fit in? Well, Middleware often has to link in some way to the Frontend or Frontend oriented backend systems. The Oracle SOA Middleware is heavily XML/SOAP based and the Frontend likes JSON and REST services a lot better. This is a gap which needs to be bridged.

SOAP and REST services

Oracle supplies an HTTP binding adapter which can be used to send and receive HTTP requests. See http://docs.oracle.com/cd/E25054_01/dev.1111/e10224/sca_bindingcomps.htm#autoId3 for more information. This adapter allows sending/receiving HTTP GET and POST requests and is capable of receiving XML from REST services. The Spring component can also be used for REST service interaction and since it is custom Java code which is used, it can more easily be expanded with additional functionality; http://technology.amis.nl/2009/12/16/soa-suite-11g-using-spring-component-to-mimic-http-binding-and-integrate-restful-services/

JSON and XML

Java

When examining the differences between JSON and XML, one major problem arises; there can be no strict fixed conversion between the two. See for example the below article on a user forum of one of the better known/performing JSON libraries (Jackson JSON); http://jackson-users.ning.com/forum/topics/xml-to-json-conversion-using; JSON and XML information models are fundamentally incompatible. Jackson JSON is good at converting JSON to Java objects and the other way around. Converting to XML however will most likely not be implemented because of the difference in information models.

JSON-lib (http://json-lib.sourceforge.net/) however does allow a conversion of JSON to XML and the other way around (although not reversible) with relatively little code. Of course certain assumptions need to be made to allow the conversion to work. If you're interested, you can read more about this on; http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html

XSLT

Going from XML to JSON is specific and can be modeled using XSLT to be able to support different conversion patterns. See http://controlfreak.net/xml-to-json-in-xslt-a-toolkit/ for some useful examples.

Conversion JSON to XML and XML to JSON webservice

I wanted to be able to easily convert JSON from the webinterface and REST services (Java code) to XML in order to be more flexible in BPEL with for example XPATH and XSLT. When I have XML, I can use XPATH to create the relevant JSON again if the default transformation is insufficient. I created a webservice based on JSON-lib to do the conversion. I used JAX WS to make developing/exposing the methods as a webservice easy. The code required is the following;

package ms.testapp.jsonxml;

import java.io.InputStream;
import java.io.InputStreamReader;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.xml.XMLSerializer;

import org.apache.commons.lang.StringEscapeUtils;

@WebService
public class JsonXml {
   
    @WebMethod
    @WebResult(name = "xml")
    public String JsonToXml(@WebParam(name = "namespace")String namespace, @WebParam(name = "rootelement")String rootelement,@WebParam(name = "jsonstring")String jsonStr) {
            XMLSerializer serializer = new XMLSerializer();
            serializer.setRootName(rootelement);
            serializer.addNamespace("", namespace);
            JSON json = JSONSerializer.toJSON(jsonStr);
            String xml = serializer.write(json);
           
            return xml;
    }

    @WebMethod
    @WebResult(name = "json")
    public String EscapedXmlToJson(@WebParam(name = "xmlstring")String xmlStr) {
        XMLSerializer xmlSerializer = new XMLSerializer();
        JSON json = xmlSerializer.read(StringEscapeUtils.unescapeXml(xmlStr)); 
        return( json.toString() ); 
    }
   
    @WebMethod(exclude=true)
    public String XmlToJson(@WebParam(name = "xmlstring")String xmlStr) {
        XMLSerializer xmlSerializer = new XMLSerializer(); 
        JSON json = xmlSerializer.read( xmlStr ); 
        return( json.toString() ); 
    }
/*
    public static void main(String[] args) {
        String Json = "{'foo':'bar',\n" +
        " 'coolness':2.0,\n" +
        " 'altitude':39000,\n" +
        " 'pilot':{'firstName':'Buzz',\n" +
        "          'lastName':'Aldrin'},\n" +
        " 'mission':'apollo 11'}";
        String Xml = new JsonXml().JsonToXml("http://www.google.com","root",Json);
        System.out.println(Json);
        System.out.println(Xml);
        Json = new JsonXml().XmlToJson(Xml);
        System.out.println(Json);
        String escapedXml = StringEscapeUtils.escapeXml(Xml);
        System.out.println(escapedXml);
        Json = new JsonXml().EscapedXmlToJson(escapedXml);
        System.out.println(Json);
       
    }
*/
}

The full code is available here; https://dl.dropbox.com/u/6693935/blog/JsonXmlApp.zip. There is also a JAR deployment profile (in addition to the WAR deployment profile) in the package and the dependencies are included. For Java developers, it is recommended (for performance reasons to avoid webservice overhead) to use the Jar deployment profile. From BPEL (in a service oriented landscape) it is more easy to have the functionality available as a webservice. The main method has been used as a sort of unittest.

Please mind, the conversion is not reversible and specific.I personally think the JSON to XML conversion is more useful then the XML to JSON conversion since that can be achieved more specifically with XSLT. I have not exposed the XmlToJson method since it's hard to call the method as a webservice with an XML parameter containing a non-escaped XML fragment.

The method of converting JSON to XML, has the benefit of not requiring an XSD schema describing the XML for the conversion and not requiring a Java object representation of the data. This has the benefit that one service/class is enough to do the conversions different messages (at least JSON to XML).

Further suggestions; JSON and BPEL

When you want to use the XML created by converting JSON in BPEL, you need to do the following;
- create a schema for the created XML message and include it in a used WSDL file
- create a variable using this schema
- use ora:parseEscapedXML to assign the output of the JsonToXml to the variable
- use the variable however you like

Because this can be cumbersome (creating the schema from the XML message, JDeveloper has a wizard but still...), it's advisable to create another webservice with two input variables; JSON string and JSON path expression returning the result of the JSON path expression on the JSON string. This can easily be accomplished by using for example http://code.google.com/p/json-path/. This way if you want to use a single variable from the JSON string, you can query for it directly and you don't need to create an XSD schema for the result of the JSON to XML conversion since it is a simple string. Use can use something like; String result = JsonPath.read(jsonstring, jsonpathstring).toString(). This is however not recommended if you need a lot of variables from the JSON string since calling a webservice is also overhead and might cost performance.

Packaging the above JSON samples in an XPATH library (see for example http://docs.oracle.com/cd/E23943_01/dev.1111/e10224/bp_appx_functs.htm) might be a better solution then wrapping them in webservices since it further increases their ease of use and performance in BPEL. If the services need to be re-used outside of BPEL by for example other middleware products, webservices might be the better solution.