AnsweredAssumed Answered

Webservices and JSON

Question asked by gil.fernandes on Jan 28, 2008
Latest reply on Sep 1, 2010 by rhozillez
Hi, there,

We just wanted to share our experience concerning JSON and Webservices here on this forum.

We have been working on a web service, which browses through Alfresco and sends the result of each browsing action to the client as a JSON string. At first we thought, I just would download http://www.json.org/json2.js and paste it into my web services javascript file and I could stringify the folder object. This did not work. It seems you cannot stringify native Java objects without having problems with stack overflows. So what I did was to create my own Javascript object which wraps around the native Java object. This object could then be "stringified" and sent to the Ajax client.

Here is the code that is currently working for our JSON based webservice:


/*
    json.js

(modified 2006-09-07): added support for RHINO
(modified 2006-05-02): json.parse, json,stringify added

   USAGE:
   var jsObj = JSON.parse(jsonStr);
   var jsonStr = JSON.stringify(jsObj);
*/
if (!this.json) {
   var json = (function () {
       var m = {
               '\b': '\\b',
               '\t': '\\t',
               '\n': '\\n',
               '\f': '\\f',
               '\r': '\\r',
               '"' : '\\"',
               '\\': '\\\\'
           },
           s = {
               array: function (x) {
                   var a = ['['], b, f, i, l = x.length, v;
                   for (i = 0; i < l; i += 1) {
                       v = x[i];
                       f = s[typeof v];
                       if (f) {
                           v = f(v);
                           if (typeof v == 'string') {
                               if (b) {
                                   a[a.length] = ',';
                               }
                               a[a.length] = v;
                               b = true;
                           }
                       }
                   }
                   a[a.length] = ']';
                   return a.join('');
               },
               'boolean': function (x) {
                   return String(x);
               },
               'null': function (x) {
                   return "null";
               },
               number: function (x) {
                   return isFinite(x) ? String(x) : 'null';
               },
               object: function (x) {
                   if (x) {
   
                       if (x instanceof Array) {
                           return s.array(x);
                       }
                       if (x.hashCode) return s.string(''+x.toString());
   
                       var a = ['{'], b, f, i, v;
                       for (i in x) {
                           v = x[i];
                           f = s[typeof v];
                           if (f) {
   
                               v = f(v);
   
                               if (typeof v == 'string') {
                                   if (b) {
                                       a[a.length] = ',';
                                   }
                                   a.push(s.string(i), ':', v);
                                   b = true;
                               }
                           }
                       }
                       a[a.length] = '}';
                       return a.join('');
                   }
                   return 'null';
               },
               string: function (x) {
                   if (/["\\\x00-\x1f]/.test(x)) {
                       x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                           var c = m[b];
                           if © {
                               return c;
                           }
                           c = b.charCodeAt();
                           return '\\u00' +
                               Math.floor(c / 16).toString(16) +
                               (c % 16).toString(16);
                       });
                   }
                   return '"' + x + '"';
               }
           };
   
      return {
         parse: function(s) {
            try {
               return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                  s.replace(/"(\\.|[^"\\])*"/g, ''))) &&
                  eval('(' + s + ')');
            } catch (e) {
               return false;
            }
         },
         stringify: s.object
      };
   })();

}

var WEBSERVICE_PATH = '/com/onepoint/alfresco/webservices/folderbrowser';

/**
* This is a Javascript object that can be used
* for JSON serialization.
* @param folder The Java object that is going to be transformed into a Javascript object.
*/
function JsonFolder(folder) {
   this.displayPath = folder.displayPath;
   this.name        = folder.name;
   this.hasParent   = folder.parent.parent != null;
   this.parentPath  = escape(encodePath(folder.parent));
   this.folders     = new Array();
   this.files       = new Array();
   this.fileLinks   = new Array();
   
   for(var i = 0, length = folder.children.length; i < length; i++) {
      var child = folder.children[i];
      if (child.isContainer) {
         this.folders[this.folders.length] = escape(encodePath(child));
      }
      else {
         this.files[this.files.length] = escape(encodePath(child));
         var childName = child.name != null ? child.name : "";
         this.fileLinks[this.files.length] = escape(url.serviceContext + "/api/node/content/"
            + child.nodeRef.storeRef.protocol + "/" + child.nodeRef.storeRef.identifier + "/"
            + child.nodeRef.id + "/" + childName);
      }
   }
}

/**
* Encodes the path of one node.
* @param node The node that is to be encoded.
*/
function encodePath(node) {
   var path = "";
   if(node.parent) {
      path = node.name;
      path = encodePath(node.parent) + '/' + path;
   }
   return path;
}

// locate folder by path

if ((args.p == null || args.p.length == 0) && (url.extension == null || url.extension.length == 0))
{
   status.code = 400;
   status.message = "No folder has been specified.";
   status.redirect = true;
}
else {
   var folder = roothome.childByNamePath(args.p != null ? args.p : url.extension);
   model.folder = folder;
   var jsonFolder = new JsonFolder(folder);
   model.jsonFolder = json.stringify(jsonFolder);
}

The modified JSON was downloaded from http://www.cosmocode.de/en/blogs/detman/json_rhino_pitfalls/ and was slightly modified. This page contains an interesting blog article about JSON and RHINO.

Just one question to the forum moderators: do you think it is worth while posting this information to the Alfresco WIKI? Currently there are no working JSON Web services examples there.

Best regards,

Gil

Outcomes