Meta Data Driven User Interface with Dojo and Spring MVC

5

What I mean with a meta data driven user interface is an application whose appearance and behavior is managed by a special set of data that is stored in a database and that is linked to attributes of the user. For instance the organization to which the user belongs has a contract whith the web application provider that enables the user to get certain types of information and disables other types. Therefore, a user interface widget, as for example a tree, should display nodes according to the set meta data that is connected to this user. Question is now how set up this stuff using Dojo for the presentation layer and Spring for the server side?

....

Dojo is a JavaScript toolkit. In a relative fast and easy way one might create rich client user interface components that contain a lot of behavior. It merely comes down to copy-paste the example code on dojotoolkit.org. So for example a tree could (thanks to Jeroen van Wilgenburg) look like this :

<div dojoType="TreeRPCController" RPCUrl="tree.do"    widgetId="treeController" DNDcontroller="create"></div>

<div dojoType="TreeSelector" widgetId="treeSelector"></div>

<div dojoType="Tree" objectId="1" controller="treeController"    selector="treeSelector" sizeMin="20" sizeShare="25"    widgetId="firstTree"><div dojoType="TreeNode" title="hello world" objectId="X1"    childIconSrc="" isFolder="true" onclick="printSelected()"></div></div>

<script type="text/javascript">dojo.event.topic.subscribe("firstTree/titleClick", printSelected);

function printSelected(evt){    dojo.debug("event: " + evt);    dojo.debug(evt.source.title);    dojo.debug(evt.source.objectId);    var sel=dojo.widget.byId(evt.source.widgetId);        var node=sel.titleNode;    if (evt.event.ctrlKey){        if (dojo.html.hasClass(node,"treeSelect")) {            dojo.html.removeClass(sel.titleNode,"treeSelect");        } else {                            dojo.html.addClass(sel.titleNode,"treeSelect");        }    }}</script>

Personally I am not so familiar with JavaScript, and some parts of the code above are a bit magical to me. However it not necessary to worry too much about it, as the complexities are hidden in the JavaScript libaries. Simply installing the JS libaries, syle sheets and copy these HTML lines, results in a nice tree widget.

Dojo makes Ajax calls. This is what we see above in the first element, that has the Dojo type TreeRPCController. When transporting data to the server, Dojo uses JSON, which means JavaScript Object Notation. This is a lightweight data-interchange format (see json.org). Please note the word “lightweight” here. JSON looks like a Map. You can create a JSON object and then put name-value pairs into it. JSON objects can be put into an array:

          JSONObject obj = new JSONObject();          obj.put("name", "Jan-Peter Balkenende");          obj.put("address", "The Hague");          ...          JSONArray arr = new JSONArray();          arr.put(obj);          arr.put(obj2);          ...

This view technology has the benefit that it is just the data that is transported from the server to the client. For instance when the user expands the tree by clicking a node, it is only the data (and the data only) in JSON format that is traveling tru cyberspace to the browser. A Dojo tree should give the user the experience of a quick widget. This can be enhanced by (1) the fact that the nodes reside in the DOM tree, and therefore are not retrieved again from the server when a node is expanded a next time again, (2) the asynchrone communication of Ajax enables the user to continue working when some operation takes time, and (3) user interface actions can be anticipated and data retrieval already prepared in the background.

Summarized: a rich user interface can be created with good programmer productivity and having a good user experience and performance. JavaServer Faces seems to be a popular framework to build front end applications. The exitement around the announcement by Oracle that ADF Faces soon will come up with a rich client renderer, amazed me because creating nice and user friendly web sites is possible since the introduction of DHTML in 1998. It’s like being exited when you buy a car that contains an airbag or electric windows. An other characteristic of JSF that keeps bothering me is that each request results in the construction and transportation of a complete web page together with repetitive boilerplate content. Why not just the data? It appears to me as a fat thing. (For more JSF bashing, check out timshadel.com/2006/01/19/jsf-the-7-layer-burrito-i-wont-eat-again.)

So far the presentation layer. On the server side we have Spring MVC, service objects, a Dao layer and the good old Oracle database. How could these classes be organized to configure the application behavior by means of the meta data, and to process the Ajax requests send by the Dojo client? We created the following components:

1. MetaDataService. An ordinary Java class on the service layer delivers meta data, for example a MetaTree domain object. This meta tree contains a list of nodes that are retrieved by MetaDataDao object from Oracle. The MetaTree defines the structure of the tree widget for the current user. When querying this tree definition from the database, attributes of a customized Acegi User are taken into account. Of course the MetaDataDao bean is wired into the service by IoC.

2. LoginController. For the time being (because there might be a more elegant solution), the MetaDataService is called by a class that handles the login request. It initializes the application by retrieving the meta data from the service layer and storing it on the session. We use the HttpSession object because it can be accessed quickly and also directly from the view.

3. DojoActionController. The Dojo-Ajax calls are mapped to handlers that have the super type DojoActionController. In the example above, the Dojo attribute:

    RPCUrl="tree.do"

means that the calls are mapped to an URL that contains “tree.do”. The Spring ServletDispatcher is instructed only permit “.do” URL’s, and “tree” is mapped to the TreeController, which is a DojoActionController. The latter is a Spring MultiActionController. As the name suggests, a MultiActionController, consists of multiple methods, like for example in case of a tree widget, expanding a tree, or maybe move tree nodes, et cetera. The question is now, when a Dojo-Ajax tree widget is just mapped to the URL pattern “tree.do” and therefore just to a specific MultiActionController, how do we know which specific event on the tree widget is linked to which specific method of the controller? This can be done in an elegant way by means of the Spring class ParameterMethodNameResolver! One of the things this class can do is map the value of a request parameter to a method in the handler. In our example the Dojo parameter “action” is mapped to the methods in the TreeController. Expanding a tree in Dojo results in the Ajax call with parameters:

    <bean id="treeController" class=".....TreeController">      <property name="treeService">        <ref bean="treeService" />      </property>                         <property name="methodNameResolver">        <ref local="dojoActions" />      </property>    </bean>         <bean id="dojoActions"        class="org.springframework.web.servlet.mvc.multiaction.        ParameterMethodNameResolver">      <property name="paramName"><value>action</value></property>    </bean>

This is really beautifull, don’t you think? The latter bean definition “dojoActions” relates to ALL events of ALL Dojo widgets. The TreeController contains a method getChildren() in order to handle the expand node event of the Dojo tree. Other events of the tree will get their own method in the TreeController. Other Dojo widgets will get their own Controller class. The DojoActionController class is the super class that contains common functionality. For example a method that gets specfic meta data from the session. Or for example a method that writes directly to the HttpServletRespons object in order to transport the JSONArray back to the browser.

4. DojoWidget bean. An extra, third parameter of the MultiActionController methods is the command class. This is an ordinary Java class that has attributes that map to the request parameters and whose values are automatically bound to the bean. For example, see the signature of the getChildren() method of the TreeController:

    public void getChildren(HttpServletRequest request,       HttpServletResponse response, DojoWidget bean)     throws ServletException, IOException, MetaDataNotFoundException

The DojoWidget bean is a domain object that contains the data JSON string transported by Dojo to the server. In this example the DojoWidget bean is used to construct a TreeNode domain object that represents the current node in the Dojo tree that the user wants to expand. In JSF terms this might be compared with the socalled backing bean.

5. MetaTree. Now we know the current tree node, we need to know what kind of node is the next level in the tree, in order to know what kind of nodes we need to request form the TreeService. Therefore we consult the meta data stored on the session, in this case the MetaTree domain object. This object returns the node type that the user is entitled to. Please note that the tree is generic and dynamic. It doesn’t matter what kind of objects it displays as long as the meta data is in synch with the base dataset. And also certain subscriptions or contracts of customers give permission to extra respectively less tree levels.

6. TreeService. Finally a service bean is called, passing in the current and the next tree nodes, in order to retrieve the tree node data from Oracle. These nodes are wrapped up into JSON format and transported to the browser.

Share.

About Author

5 Comments

  1. Erik Kerkhoven on

    Hello Jie, I completely agree with you about the fact that our Controller is no longer unware about the view technology. A JsonView is indeed good news. Can you send me more details, an URL for example, about that? Thank you very much for your reaction. In an other post I describe a solution we came up with regarding the integration of Dojo and Spring’s SimpleFormController, see: http://technology.amis.nl/blog/?p=1486. This is also a difficult issue. Did you already think about that? Maybe you can have a look at it and provide a better solution. Regards.

  2. Hi Erik, thanks for the article, I am also working on using DOJO tree where we are already using Spring. One thing with your article is the to wrap up response in JSON format (I guess in your DOJOActionControll superclass), this will tie up spring controller with specifics (JSON format) of front end. I doubt if it is a good idea. The good news is that in some of the discussion forum, we already find a way to extend Spring’s view object, such as define a JsonView which we override the renderMergedOutputModel method to have it return the data with JSON format. I think it is a better way to extend Spring and not have its controller tied up with view. Hope this will help.
    Jie

  3. Hi guys, Thanks for your reaction. The problem with sending the source is that we are working on a project that that has a non disclosure agreement. But if you have questions, maybe I can answer. You might also contact AMIS sales representative Reinier at Reinier.Beenen@AMIS.nl.

  4. Christophe TAVERNE on

    Hi,

    Thank you a lot for you article!
    very interesting.

    I’m agree with John. Please could you send us a sample?
    some part aren’t clear for me and it could help me a lot.

    Thanks

    Regards
    Chris

  5. Eric,

    Do you have a sample application demonstrating this that you could send me. I would like to study it for a project that I am working on.

    Best Regards,

    John Boyd