Raible's Wiki

Raible Designs
Wiki Home
News
Recent Changes

AppFuse

Homepage
  - Korean
  - Chinese
  - Italian
  - Japanese

QuickStart Guide
  - Chinese
  - French
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish
  - Japanese

User Guide
  - Korean
  - Chinese

Tutorials
  - Chinese
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish

FAQ
  - Korean

Latest Downloads

Other Applications

Struts Resume
Security Example
Struts Menu

Set your name in
UserPreferences


Referenced by
...nobody




JSPWiki v2.2.33

[RSS]


Hide Menu

Sandbox


This is version 3. It is not the current version, and thus it cannot be edited.
[Back to current version]   [Restore this version]


In my day job, we decided to use a little XMLHttpRequest lovin' to populate one drop-down from another. This is my review of JSON-RPC, an open source JavaScript library and servlet for simplifying XMLHttpRequest. I considered integrate Direct Web Remoting (DWR) as well, but its java.net site was down the day I needed it. I started out with JSON-RPC 0.7, which caused some conflicts with Commons Validator client-side validation. This was fixed in the 0.8 release. JSON-RPC takes a little more setup than I care for, but it's pretty easy nonetheless:

  1. Download the 0.8 release from http://oss.metaparadigm.com/jsonrpc-dist/json-rpc-java-0.8.tar.gz.
  2. Add the JAR to your project and the webapps/jsonrpc/jsonrpc.js to your projects' "scripts" folder. Include this file in your SiteMesh decorator or Tiles layout. If you're not using SiteMesh or Tiles, it's high time you started.
  3. JSON-RPC currently requires that you register each class you want call methods on. In our project, I registered a Spring bean (LookupHelper) that's a singleton with references to Maps in the ServletContext. Then we used JavaScript functions to call JSON-PRC and look up units for a plant, and vice versa. I'm not going to put the LookupHelper class here - you'll have to trust its methods return a single String or a comma-separated list of Strings. To register this bean with JSON-RPC, I created an HttpSessionListener and configured it in web.xml.


    /**
     * UserListener class used to add/remove session attributes when
     * a user first logs in.  Mainly for JavaScript Remote Scripting stuff.
     *
     @author Matt Raible
     */
    public class UserListener implements HttpSessionListener, HttpSessionAttributeListener
            private final Log log = LogFactory.getLog(UserListener.class);
        public final static String BRIDGE_KEY = "JSONRPCBridge";

        /**
         * Initializes LookupHelper singleton with values needed for lookup
         *
         @param event the HttpSessionEvent to grab session information from
         */
        public void sessionCreated(HttpSessionEvent event) {
            // Find the JSONRPCBridge for this session or create one
            // if it doesn't exist. Note the bridge must be named BRIDGE_KEY
            // in the HttpSession for the JSONRPCServlet to find it.
            HttpSession session = event.getSession();
            JSONRPCBridge jsonBridge = new JSONRPCBridge();
            jsonBridge.setDebug(true);
            session.setAttribute(BRIDGE_KEY, jsonBridge);
        }

        /**
         * Destroys LookupHelper
         *
         @param event the HttpSessionEvent to grab session information from
         */
        public void sessionDestroyed(HttpSessionEvent event) {
            if (event.getSession() != null) {
                event.getSession().removeAttribute(BRIDGE_KEY);
            }
        }

        public void attributeAdded(HttpSessionBindingEvent event) {
            if (event.getName().equals(BRIDGE_KEY)) {
                HttpSession session = event.getSession();
                // register LookupHelper so we can call methods on it
                ApplicationContext ctx =
                        WebApplicationContextUtils
                        .getWebApplicationContext(session.getServletContext());

                // check for null so we don't have to initialize Spring in tests
                if (ctx != null) {
                    log.debug("Registering lookupHelper for XmlHttpRequest...");
                    JSONRPCBridge jsonBridge =
                        (JSONRPCBridgesession.getAttribute(BRIDGE_KEY);
                    jsonBridge.registerObject("lookupHelper",
                                              ctx.getBean("lookupHelper"));
                }
            }
        }

        public void attributeRemoved(HttpSessionBindingEvent event) {
            // don't care
        }

        public void attributeReplaced(HttpSessionBindingEvent event) {
            // same as attribute added
            attributeAdded(event);
        }
    }

  4. After this setup was complete, I was able to add the following JavaScript to the bottom of my JSP. These are functions that our drop-downs call to populate each other, and keep their options in synch.
    var jsonurl = "${ctx}/jsonrpc";
        var jsonrpc = null;
        var unitDropDown = document.getElementById("equipmentName");
    

    function filterUnits(plantDropDown) { var plantName = plantDropDown.optionsplantDropDown.selectedIndex.value;

    if (plantName == "") { reloadUnits(""); return; }

    try { jsonrpc = new JSONRpcClient(jsonurl); } catch(e) { alert(e); }

    // Call a Java method on the server var units = jsonrpc.lookupHelper.getUnitsForPlant(plantName); setUnits(units); }

    function reloadUnits(value) {

    if (value == "") { try { jsonrpc = new JSONRpcClient(jsonurl); } catch(e) { alert(e); }

    // Call a Java method on the server var units = jsonrpc.lookupHelper.getAllUnits(); setUnits(units); } }

    function setUnits(units) { var unitArray = units.split(",");

    unitDropDown.options.length = 1; // keep "All" option for (i=0; i < unitArray.length; i++) { unitDropDown.optionsunitDropDown.options.length = new Option(unitArray[i], unitArray[i]); } }

The hardest part of using JSON-RPC is setting it up. We only experienced minor issues with Commons Validator, but since the JSON-RPC 0.8 release - everything has worked great, on all browsers we need to support. The only thing I don't like about this library is that you have to register objects for each user's session. I briefly looked at DWR and it looks a little cleaner - especially b/c of its Spring integration. The next time we need XMLHttpRequest, we'll probably use DRW just to compare the two.



Go to top   More info...   Attach file...
This particular version was published on 06-Nov-2006 13:52:44 MST by MattRaible.