cancel
Showing results for 
Search instead for 
Did you mean: 

Webservices and JSON

gil_fernandes
Champ in-the-making
Champ in-the-making
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
9 REPLIES 9

pmonks
Star Contributor
Star Contributor
It would be *great* if you could post this example to the wiki!  http://wiki.alfresco.com/wiki/Web_Scripts_Examples is probably the most appropriate place for this.

Thanks for contributing!

gil_fernandes
Champ in-the-making
Champ in-the-making
Hello,

I have just modified the page http://wiki.alfresco.com/wiki/Web_Scripts_Examples#JSON_example . I hope this goes OK with you. I am quite unexperienced, so if I did something wrong, please do not hesitate to tell me.

Regards,

Gil

davidc
Star Contributor
Star Contributor
Have you tried using a Freemarker template to render the JSON response?  Templates are so much easier to read and maintain than lots of string manipulation code.

gil_fernandes
Champ in-the-making
Champ in-the-making
Hello,

This is the Freemarker code I have used:

${jsonFolder}

This renders the JSON ouput in connection with the posted js file.

Kind regards,

Gil

gil_fernandes
Champ in-the-making
Champ in-the-making
Hello,

As a matter of fact, my first idea was to use Freemarker to render JSON strings.

Yet I then thought that it would be a better approach to use Javascript. Because I wanted to have some JSON functions that I could use ALWAYS to render JSON based Web scripts. So I have now a good piece of code that I can reuse.

Perhaps the Javascript solution is also faster than Freemarker.

Kind regards,

Gil

hkır
Champ in-the-making
Champ in-the-making
I know this topic is pretty old but I think http://wiki.alfresco.com/wiki/Web_Scripts_Examples page needs a modification. Because when I tried this script, I lost a lot of time, till I found jsonUtils in this page
http://www.springsurf.org/sites/1.0.0.M3/spring-webscripts/spring-webscripts-documentation/reference... . I think you should mention about jsonUtils.toJSONString and jsonUtils.toObject functions in this page.

mrogers
Star Contributor
Star Contributor
Please don't post stuff like this to the forums.   If you note something wrong with the community wiki pages then just go adead and fix it.

iblanco
Confirmed Champ
Confirmed Champ
I did the change. As far as I undestood the old example wasn't necessary any longer, so I replaced it with a freemarker based one.

Bye.

rhozillez
Champ in-the-making
Champ in-the-making
HI

im new in this forum..
thanks.. Smiley Very Happy