Using JSON to Exchange Data with Web Services in XFA Forms

Continuing from my previous post on extending the JavaScript prototype property, another most under-utilized technique is the use of JavaScript Object Notation (JSON) as a data exchange format between a form and web services. Did you ever think of using JSON in form development? No? Me neither. I never thought of it until one of my customers suggested the possibility. It was an elegant solution, as our web services were getting more complex, we were wrestling on reading the data versus implementing solutions. JSON gave us a way to reduce hassle of working with complex objects.

If you are reading, you probably know what JSON is. But if you don’t, you can learn more about it at http://www.json.org/.

In this Service Oriented Architecture (SOA) era, I believe that most forms retrieve data from (or submit to) external sources via web services. Web services are great as they allow to a wide variety of clients to consume the services. Web service responses could range from a few pieces of data or a large set of data (e.g. array). Working with latter type of XML response is a lot harder if you need to conditionally hide/show certain item in the list or use the data in another form or fashion. In this situation, JSON is ideal.

So before you do anything to the form, you need to modify your web service to return a JSON formatted string. Instead of returning an ArrayList or Array of objects from the web service operation (Java), you have to convert your array into a JSON string. I use JSON-lib (net.sf.json.JSONArray) but you can any JSON library you prefer. Here is sample code:


public String getSimpleArray()
{
Person[] people = {
new Person("John", "Doe", "235-235-5466", "john@doe.com"),
new Person("Tom", "Green", "444-235-2343", "tom@green.com")
};
JSONArray jsonArray = JSONArray.fromObject(people);
return jsonArray.toString();
}

The web service response should look similar to the following snippet:


<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getSimpleArrayResponse xmlns:ns1="http://consulting.adobe.com/">
<return xmlns="http://consulting.adobe.com/">[{"email":"john@doe.com","firstname":"John","lastname":"Doe","phone":"235-235-5466"},{"email":"tom@green.com","firstname":"Tom","lastname":"Green","phone":"444-235-2343"}]</return>
</ns1:getSimpleArrayResponse>
</soap:Body>
</soap:Envelope>

As you can see, the soap body only contains one element, which is a JSON structured string. To utilize this in your form, simple create a data connection to this web service operation and bind the return element to a text field. Then convert the raw value of the text field to a JSON object by using the eval() function.


// wsResponse is a text field and is bound to the web service return element.
var people = eval('(' + wsResponse.rawValue + ')'); // or wsResponse.rawValue.evalJSON(); if you use the String prototype extension from my previous post.

This gives you an array of JavaScript objects called "people". You can now access this array just like any other native JavaScript arrays. Below are some examples:


// loop through the array
for(var i = 0; i < people.length; i++)
{
var person = people[i];
textField.rawValue += person.firstname + " " + person.lastname + "\n";
}

// get the email of the last person in the array
var email = people[people.length - 1].email;

Yeah, it’s that simple. Now you can forget about how to access your data and focus on how and where to use the. As a side note, there are some security concerns with JSON regarding code insertions attacks etc. There are some open-source libraries that handle these issues.

I don’t have any samples handy. However, you need one, leave a comment and I will post one. Thanks.

Resources