Dojo + jabsorb

By on June 18, 2008 12:01 am

jabsorb is lightweight Ajax framework that uses JSON-RPC to communicate method calls from JavaScript to the Java server. Because of Dojo’s pluggable RPC and SMD capabilities, Dojo can easily be used to communicate method calls to the jabsorb server framework. Together, Dojo and jabsorb provide a very simple solution for integrating a UI with a Java back-end. Here we will see a quick demonstration of making a Java object available for remote calls from Dojo.

First, we build a Java class that will return a polite hello to whomever called it:

public class Hello {
   public String sayHello(String who)
   {
     return "hello " + who;
   }
}

Next, we expose an object instance of this class to the jabsorb framework in JSP:




<% JSONRPCBridge.registerObject("hello", hello); %>
...

Here we register an object called “hello” which is an instance of the Hello class. The jabsorb method naming convention defines that in order to call the sayHello method on the hello object, we call the method “hello.sayHello” using JSON-RPC. Now we create an RPC service in Dojo. We use an SMD definition to define the service that is available jabsorb:

dojo.require("dojox.rpc.Service");
dojo.require("dojox.rpc.JsonRPC");
var services = new dojox.rpc.Service({
	target:"/jabsorb-1.2/JSON-RPC",
	transport:"POST",
	envelope:"JSON-RPC-1.0",
	contentType:"application/json",
	services:{
		"hello.sayHello":{ // this is the method that we created in jabsorb
			returns:{"type":"string"},
			parameters:[{"type":"string"}]
		}
	}
});

We now have a services object that we can use to call the hello object. We can call the sayHello method on the server by calling the “hello.sayHello” method on the services object:

var deferred = services["hello.sayHello"]("Fred");
	deferred.addCallback(function(result) {
		alert(result);
	})

This calls the sayHello method with argument of “Fred”, which will return “hello Fred”. When the response is received from the server, the deferred object will be fulfilled, and the alert will give the friendly response.

In Dojo 1.2, we have provided “namespaced” service resolution, so this method would be available as services.hello.sayHello rather than services["hello.sayHello"]:

var deferred = services.hello.sayHello("Fred");

jabsorb is an easy to use server framework for handling remote method calls to Java objects using JSON-RPC. With Dojo’s pluggable service architecture, it is simple to connect Dojo to jabsorb to interact with existing Java code. jabsorb is one of a growing number of server frameworks that integrates well with Dojo.

Comments

  • Pingback: SitePen Blog » Dojo JSON-RPC + Java()

  • Russell Jones

    Could you set out the advantages this has over using jabsorb’s vanilla jsonrpc.object.method() please?

  • The primary advantage to this approach is the integration with Dojo. The RPC calls return the familiar Dojo Deferred object which uses the same interface async handling as other async operations in Dojo. The service can also be used seamlessly Dojo’s other service consumers, for example the service could be used in the ServiceStore to adapt it to the data source API for use by various widgets like the tree and grid.

  • Russell Jones

    One shortcoming of this is that the set of methods on the Jabsorbed object are not automatically available. One has to write the SMD JSON for them. It’d be nice if Jabsorb could provide it, as you say at
    http://www.mail-archive.com/jabsorb-dev@lists.jabsorb.org/msg00152.html

    Arthur seems to agree as per http://www.mail-archive.com/jabsorb-dev@lists.jabsorb.org/msg00147.html
    but I guess it’s not a priority for him.
    Has any progress been made with this that you know of? What’s needed?

  • Russell Jones

    Also, would you mind posting the SMD for a dojox.data.ServiceStore, if you’ve written one?

  • @Russell:
    The SMD used is the object that is passed to the ServiceStore in the example above:
    {
    target:”/jabsorb-1.2/JSON-RPC”,
    transport:”POST”,
    envelope:”JSON-RPC-1.0″,
    contentType:”application/json”,
    services:{
    “hello.sayHello”:{ // this is the method that we created in jabsorb
    returns:{“type”:”string”},
    parameters:[{“type”:”string”}]
    }
    }
    }

  • Russell Jones

    Sorry to be a bit slow, but how can that work? Doesn’t the ServiceStore require an implementation of the dojo.data.ItemFileReadStore ? Would one specify all the methods in that object using SMD, then implement them in the Jabsorbed JAVA object, presented to dojo as above? Or am I missing something?

  • Russell Jones

    Sorry, I mean dojo.data.api.Read

  • Russell Jones

    Going to read the source code. Won’t bug you again until I’ve done that.

  • Russell Jones

    OK, some comments on the comments:

    // note that dojox.rpc.Service is not required, you can create your own services
    (how? using what?)

    —-

    // A ServiceStore is a readonly data store that provides a data.data interface to an RPC service.
    // var myServices = new dojox.rpc.Service(dojo.moduleUrl(“dojox.rpc.tests.resources”, “test.smd”));
    // var serviceStore = new dojox.data.ServiceStore({service:myServices.ServiceStore});

    I suggest this would be clearer as

    // A ServiceStore is a read-only data store that provides a dojo.data.Read interface to an RPC service.

    // Example usage 1:
    // var myServices = new dojox.rpc.Service(dojo.moduleUrl(“dojox.rpc.tests.resources”, “test.smd”));
    // var serviceStore = new dojox.data.ServiceStore({service:myServices.ServiceStore});

    What is in test.smd?
    How would we access the values?

    // Example usage 2 (with jabsorb 1.2):

    /*
    Java class:
    public class Hello {
    public String sayHello(String who)
    {
    return “hello ” + who;
    }
    }

    JavaScript:
    dojo.require(“dojox.rpc.Service”);
    dojo.require(“dojox.rpc.JsonRPC”);
    var services = new dojox.rpc.Service({
    target:”/jabsorb-1.2/JSON-RPC”,
    transport:”POST”,
    envelope:”JSON-RPC-1.0″,
    contentType:”application/json”,
    services:{
    “hello.sayHello”:{ // this is a method from a Java object exposed using jabsorb
    returns:{“type”:”string”},
    parameters:[{“type”:”string”}]
    }
    }
    });

    var serviceStore = new dojox.data.ServiceStore({service:services.hello, idAttribute: “sayHello”});
    */

    How would we access the values? Is the attribute called “sayHello”?
    Is this right?

    var item=serviceStore.fetch(
    {
    queryOptions.cache: false,
    syncMode: false,
    clientFetch: “Dojo”
    }
    );

    var value=serviceStore.getValue(item, serviceStore.getIdentity());

    Then “value” would be equal to “hello Dojo”
    —-

    // The ServiceStore also supports lazy loading. References can be made to objects that have not been loaded.
    // For example if a service returned:
    // {“name”:”Example”,”lazyLoadedObject”:{“$ref”:”obj2″}}
    //
    // And this object has accessed using the dojo.data API:
    // var obj = serviceStore.getValue(myObject,”lazyLoadedObject”);
    // The object would automatically be requested from the server (with an object id of “obj2”).

    I suggest this would be clearer as

    // The ServiceStore also supports lazy loading. References can be made to objects that have not yet been loaded.
    //
    // For example, if a service returned the following and we assigned it to the variable myObject
    // {“name”:”Example”,”lazyLoadedObject”:{“$ref”:”obj2″}}
    // then lazyLoadedObject may be loaded using the dojo.data API thus:
    // var obj = serviceStore.getValue(myObject,”lazyLoadedObject”);
    // The object would then automatically be requested from the server (with an object id of “obj2”).

  • @Russell:
    The ServiceStore implements dojo.data.api.Read (as well as dojo.data.api.Identity) for you, passing all fetch requests to the service and handling identity. You simply provide a service.

  • Pete

    If this,

    var resultArray = var deferred = services.hello.sayHello(“Fred”);

    …could be changed to this,

    var deferred = services.hello.sayHello(“Fred”).String;

    It would be a great help and simplify integrating with dojo tremendously.

    I am using Netbeans with JMaki and it does not include RPC/SMD.

    Pete