Monday, December 14, 2009

Handling JSON arrays and objects

Recently I was using the Apache Wink client-side capabilities to interface with the RESTful APIs of several popular social media sites like Twitter and bit.ly, and I ran into an interesting problem regarding handling the JSON data being returned from those services. Since I think quite a few people may hit this same issue, I thought it may be helpful to share one way of dealing with the problem.

What is the problem? Well, it turns out that in dealing with these services they were sending back JSON in two different forms. One of those forms was the object form of JSON, which looks like the following:

{"name":"Dustin", "userid":"WebSphereClouds"}

The other form that was getting sent back was the array form of JSON, which starts with a [ instead of a {:

[{"name":"Dustin", "userid":"WebSphereClouds"}]

That may not seem like a big deal, but it does in fact affect the way the data is parsed and the Java object type to which the data is converted.

For instance, consider my application which uses the IBM JSON4J library. If I were trying to convert a response input stream containing data in JSON object form, I would call JSONObject.parse(responseInputStream) and that would return a JSONObject. On the other hand, if I were converting a response input stream containing data in JSON array form I would call JSONArray.parse(responseInputStream) and that would return a JSONArray. Clearly, my application needed a way to determine what form of JSON data it was handling.

To do this, I created a simple class that encapsulates this data type determination. It contains two methods to parse a response input stream and return a JSONArtifact type which is an interface implemented by both JSONObject and JSONArray.

private enum JSONType {
ARRAY_TYPE,
REGULAR_TYPE
}
public JSONArtifact parse(InputStream is) throws IOException {
JSONArtifact parsedJSON = null;
FilterInputStream fis = new BufferedInputStream(is);
JSONType jsonType = getJSONType(fis);
if(jsonType == JSONType.ARRAY_TYPE) {
parsedJSON = JSONArray.parse(fis);
}
else {
parsedJSON = JSONObject.parse(fis);
}
return parsedJSON;
}
JSONType getJSONType(FilterInputStream fis) throws IOException {
JSONType type = null;
fis.mark(1);
byte[] bytes = new byte[1];
fis.read(bytes);
fis.reset();
String firstChar = new String(bytes);
if("[".equals(firstChar)) {
type = JSONType.ARRAY_TYPE;
}
else {
type = JSONType.REGULAR_TYPE;
}
return type;
}

The class simply reads the first byte of data from the stream, resets the stream, and then determines, based on whether the first byte is { or [, whether to parse using the JSONArray or JSONObject class.

I also want to point out what I would consider to be a best practice with respect to JSON data sent back from a RESTful service. When developing RESTful services on the server-side, I suggest sending back the object form of JSON. If necessary, you can encapsulate arrays in this object form:

{"userInfo":[{"name":"Dustin", "userid":"WebSphereClouds"}]}

This will make for simpler parsing by clients of your services, and you can easily add data to what you return by adding more entries in the JSON without regressing existing clients.

Friday, December 11, 2009

Useful JAX-RS links for testing and handling error conditions

There's some interesting articles that Dave Artus has been writing as he becomes more proficient with Apache Wink.  He has a great (in-depth) detailed article about using JMock to test JAX-RS services that he's developing with Apache Wink as well as a good article about handling error conditions.  Check it out...

Tuesday, December 8, 2009

Paper to provide an overview of SAML and support in 7.0.0.7

I hope you found the SAML demo video from Greg useful. My team has put together a paper to provide an overview of the SAML technology introduced in WebSphere 7.0.0.7.

The paper is available for download here. This paper provides:

  1. Introduction to SAML standards (a very rich set of standards and specification)
  2. Comparison of SAML to LTPA and Kerberos technology and what problem SAML is solving
  3. Different trust models based on Bearer, Holder-Of-Key, and Sender-Vouches Confirmation Methods
  4. Self-Issuance of SAML token and external third party STS (Security Token Service) issuance
  5. SAML token propagation in Web Services including different considerations for handling token timeouts
  6. Client side SAML token caching
  7. List of supported features for SAML introduced in WebSphere 7.0.0.7
  8. Introduction to the default Policy Sets for enabling SAML Token Profile support

Here is the abstract of the paper:

Abstract
Security Assertion Markup Language (SAML) is an XML based framework developed by the Organization for the Advancement of Structured Information Standards (OASIS), used for the exchange of security information between different parties. This is an open standard that can be used to exchange security information between different products. SAML support in IBM® WebSphere® Application Server Version 7.0 Fix Pack 7 delivers a SAML solution that provides support for the most common scenarios SAML using Web services.

I hope you find the paper useful and please send us any feedback.