LAB-5573: Leveraging JavaScript Toolkits for End-to-End Connectivity in Web Applications

Expected Duration: 100 minutes
Contacts: Troy Giunipero

Exercise 2: Connecting a Dojo Tree to an ArrayList using JSON (25 minutes)

 

This exercise demonstrates how to add and configure a Dojo Tree widget to a web page, and enable the server side to respond to Tree requests in JSON format. Initially, you examine how the response can be prepared programmatically, then you modify the application to respond with a static JSON file.

The completed project looks as follows:

Completed exercise viewed in browser

In order to complete this project, there are five steps you need to accomplish:

  1. Adding the Dojo toolkit to the project you are working on.
  2. Linking to the toolkit from the web page you want it to apply to.
  3. Including Dojo components and ancillary code in the web page.
  4. Adding the JSON Java package to the project and prepare logic.
  5. Preparing a servlet to initiate the JSON response.

Once you complete the project, you can experiment with the following tasks:

  1. Examining communication with the HTTP Client Monitor.
  2. Modifying the project to respond with a static JSON file.
  3. Applying different Dojo themes.

Background Information

 

The NetBeans IDE comes bundled with various toolkits, including Yahoo! UI, Dojo, Script.aculo.us, jQuery, and Prototype. In this exercise, you'll add the Dojo bundled toolkit to the development environment, and utilize a freely available Java package from json.org to process data from an ArrayList into JSON format. In doing so, you'll explore some of the development tools at your disposal.

The IDE includes version 1.2.1 of the Dojo toolkit and contains the Dojo Core and Dijit libraries. This exercise makes use of two Dojo components: Dijit's Tree widget, and the ItemFileReadStore component, provided by the Core library.



Steps to Follow

 

Step 1: Adding the Dojo Library to Your Project

  1. In the Projects window, right-click the Ex2_Dojo_Start node and choose Set as Main Project.
  2. Right-click the project node and choose Properties.
  3. In the Project Properties window, select the JavaScript Libraries category, then click the Add button.

    The Add JavaScript Libraries dialog displays, listing all JavaScript libraries registered with the IDE (excluding any libraries already added to the project).
  4. Select the Dojo library and note that the path where the library will be extracted into your project is displayed.
    Add JavaScript Libraries dialog
    Note: By default, the IDE extracts JavaScript libraries to a web/resources folder within your project. You could modify the path by clicking the ellipsis button ( ellipsis button ) in the above dialog, then navigating to a new path.
  5. Click OK. When you do so, the library is extracted to the specified location in your project.
  6. Click OK to exit the Project Properties window. In your Projects window, note that a dojo_1.2.1 node is now listed under Web Pages > resources. If you drill down into the node, you can see that the Dojo and Dijit libraries are contained therein.
    Projects window
    The Dojo library is now added to your project.

Step 2: Linking to the Toolkit from a Project File

  1. In the Projects window, double-click the dojoDemo.html file to open it in the editor.

    In order to use the toolkit, you need to link to the dojo.js file, which is the source loader for Dojo and determines the correct host environment to use. While doing so, you can also configure djConfig by adding the parseOnLoad parameter.
  2. In the dojoDemo.html file, replace the
    <!-- TODO: link to Dojo resources here -->
    comment with the following <script> tags:
    <script type="text/javascript"
        src="resources/dojo_1.2.1/dojo/dojo.js"
        djConfig="parseOnLoad: true">
    </script>
    • djConfig allows you to override global settings that control how Dojo operates (e.g., using the parseOnLoad property).
    • parseOnLoad set to true ensures that widgets and page mark-up are parsed as the page is loaded.
  3. Link to a sample theme contained in the toolkit. Dijit provides three sample themes: tundra, soria and nihilo. These are contained in the dijit/themes folder, which you can verify from the Projects window:
    Dijit theme folders displayed in Projects window
    To link to a theme, add the following @import statements to the page (add all three so that you can sample them later in the exercise). You can add these between the page's <head> tags, for example just beneath the <script> tags you just added (changes in red):
    <script type="text/javascript"
        src="resources/dojo_1.2.1/dojo/dojo.js"
        djConfig="parseOnLoad: true">
    </script>
    
    <style type="text/css">
        @import "resources/dojo_1.2.1/dijit/themes/tundra/tundra.css";
        @import "resources/dojo_1.2.1/dijit/themes/soria/soria.css";
        @import "resources/dojo_1.2.1/dijit/themes/nihilo/nihilo.css";
    </style>
  4. Add a class to the <body> tag specifying the name of the theme you want to use. When you do this, any Dojo widget which has been loaded into the page will be rendered using the styles associated with the theme.
    <body class="nihilo">

Step 3: Include Dojo Components and Ancillary Code

Once you've linked to dojo.js, you can begin adding code to utilize modules and widgets. First let's add code to load the dijit.Tree widget, and dojo.data.ItemFileReadStore using dojo.require statements. Then, add the widget and modules themselves to the page.

  1. Replace the
    // TODO: add dojo.require statements here
    comment (line 8) with the following dojo.require statements:
    dojo.require("dojo.data.ItemFileReadStore");
    dojo.require("dijit.Tree");
    • dojo.data.ItemFileReadStore: reads the JSON structured contents from an http endpoint (in this case, a servlet) and stores all the items in-memory for simple and quick access.
    • digit.Tree: The Tree widget that provides a view of the JSON data retrieved from ItemFileReadStore.
  2. Add an ItemFileReadStore and Tree widget to the page. Replace the
    <!-- TODO: specify AJAX retrieval -->
    
    <!-- TODO: add Tree widget and configure attributes -->
    comments with the following:
    <div dojoType="dojo.data.ItemFileReadStore"
        url="TribeServlet"
        jsId="indianStore">
    </div>
    
    <div dojoType="dijit.Tree"
         store="indianStore"
         query="{type:'region'}"
         label="North American Indians">
    </div>
    • ItemFileReadStore requires you to specify the url property by pointing to the server-side resource that returns the JSON data. As will be later demonstrated, this is the TribeServlet. You can use the jsId property to give the retrieved JSON data an id, which widgets can then use to refer to the data store.
    • Tree uses the store property to point to the ItemFileReadStore, which provides the JSON data. The query property enables you to arrange the display of data, based on a keyword used in the JSON file. We'll experiment with this later in the exercise.

At this stage, your dojoDemo.html file should resemble the dojoDemo.html file contained in the Ex2_Dojo_Final project. You can verify this by selecting both files (Ctrl-click; ⌘-click on Mac) in the Projects window and choosing Tools > Diff. This allows you to compare both files side-by-side.

Dojo Documentation and API Resources

Dojo provides numerous documentation, examples, and API resources:


Step 4: Adding the JSON Java Package and Preparing Logic

In this exercise, the logic that extracts the ArrayList sample data has been prepared for you. Essentially, it is only necessary to include the third-party JSON library to the project, then add import statements for these classes. In the process, we can examine these classes to understand what is necessary to convert data from an ArrayList into JSON format. Details follow:

  1. Visit http://json.org/java [Internet connection required], and note that Java classes for JSON conversion are freely available. A json.jar file is provided for you in the resources folder within the setup materials. The json.jar file is a compiled archive of these sources.

    Tip: Note that the APIs for JSON classes are defined at http://json.org/java - you may want to keep this page open as you examine code in Tribe and TribeDataManager.
  2. Add the json.jar file to the project. In the Projects window, right-click the Libraries node and choose Add JAR/Folder. Then navigate to the resources folder contained in the setup materials and select the json.jar file.
  3. Expand the Source Packages > dojo.indians package and double-click the Tribe and TribeDataManager classes to open them in the editor.
  4. Add necessary import statements to both classes. In each class, right-click in the editor and choose Fix Imports.

    The Tribe class requires the following imports:
    import dojo.org.json.JSONException;
    import dojo.org.json.JSONObject;
    
    The TribeDataManager class requires the following imports:
    import dojo.org.json.JSONArray;
    import dojo.org.json.JSONException;
    import dojo.org.json.JSONObject;
    
  5. Examine the ArrayList in TribeDataManager. The ArrayList is a collection of Tribe objects. Looking at the first element of the ArrayList, you can see a new Tribe object created and added to the list:
    indians.add(new Tribe("Eskimo-Aleut", "Arctic", "Alaska Natives"));
    Each Tribe object captures three points of information: tribe, category, and region. The data for this exercise has been taken from Wikipedia's entry on Native Americans in the United States. As you can determine, multiple tribes are classified within a category, and numerous categories may be contained within a larger region.
  6. Open the Tribe class in the editor, and note that it is basically a JavaBean, with the exception of the toJSONObject() method:
    public JSONObject toJSONObject() throws JSONException {
        JSONObject jo = new JSONObject();
        jo.put("name", this.name);
        jo.put("type", "tribe");
    
        return jo;
    }
  7. Switch back to TribeDataManager (Ctrl-Tab) and examine the methods included in the class. Open the Navigator (Ctrl-7; ⌘-7 on Mac) to view a list of fields and properties contained by the class.
    TribeDataManager class viewed in the Navigator
    The most significant method contained therein is getIndiansAsJSONObject(). This method scans the ArrayList, processes the data, and returns it in the form of a JSONObject. The String form of the JSONObject is what is required by Dojo's ItemFileReadStore.
    public static JSONObject getIndiansAsJSONObject() throws JSONException {
    
        JSONObject jo = new JSONObject();
        JSONArray itemsArray = new JSONArray();
    
        jo.put("identifier", "name");
        jo.put("label", "name");
    
        // add regions
        addRegionsToJSONArray(itemsArray);
    
        // add categories
        addCategoriesToJSONArray(itemsArray);
    
        // add tribes
        addTribesToJSONArray(itemsArray);
    
        jo.put("items", itemsArray);
        return jo;
    }
  8. Open the Javadoc on the getIndiansAsJSONObject() method. You can do this by returning to the Navigator (Ctrl-7; ⌘-7 on Mac) and hovering over the method. Otherwise, choose Window > Other > Javadoc from the main menu, then click on the method signature in the editor.
    Javadoc window opened to TribeDataManager class
  9. Examine the example of JSON data that is provided in the Javadoc. Note that the format of the data conforms to the examples provided in the Dojo documentation.

NetBeans IDE's Java Debugger

Tip: You will implement a servlet that calls the getIndiansAsJSONObject() method in the next step. Once you do this, you can use the IDE's Java debugger to step through the method and examine how the JSONObject is formed. You could do this by:
  1. setting a breakpoint on the method (click the line number (i.e., line 99) in the left margin of the editor),
    Method breakpoint set in the editor
  2. running the debugger (click the Debug Main Project button ( Debug Main Project button ) from the IDE's toolbar),
  3. using the Step Into ( Step Into button ) and Step Over ( Step Over button ) buttons in the Debugger toolbar,
  4. and examining variable and expression values in the Local Variables window (Window > Debugging > Local Variables).

Step 5: Preparing a Servlet to Initiate the Response

Recall that you specified "TribeServlet" as the value for the url property when adding the ItemFileReadStore. This is the destination on the server-side that is tasked with preparing and returning the JSON data to the client. Let's now create this servlet.

  1. In the Projects window, right-click the dojo.indians source package and choose New > Servlet.
  2. In the New Servlet dialog, type in TribeServlet for the class name. Also, have the servlet created in the dojo.indians package.
    New servlet wizard

    Click Next.
  3. Note that in the Configure Servlet Deployment step, the Add information to deployment descriptor is selected by default, meaning that the default servlet name and URL pattern will automatically be added to web.xml upon completing the wizard. Consequently, any requests to the host domain (i.e., http://localhost:8080/Ex2_Dojo_Start/) for TribeServlet will be handled by the dojo.indians.TribeServlet class.
  4. Click Finish. A skeleton class for the new servlet is generated and opens in the editor.

    The function of the servlet is to call the getIndiansAsJSONObject() method, and use the data from this method to respond to the client request. In order to prepare a response in JSON format, we have to first set the mime type of the response to JSON format.
  5. Locate the processRequest() method, and change
    response.setContentType("text/html;charset=UTF-8");
    to:
    response.setContentType("application/json");
    This sets the Content-Type header of the HTTP Response to indicate that any returned content is in JSON format.
  6. Replace the commented code within the processRequest() method's try block with the following (changes in red):
    try {
    
        JSONObject jo = null;
        try {
            jo = TribeDataManager.getIndiansAsJSONObject();
        } catch (JSONException ex) {
            Logger.getLogger(TribeServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
    
        out.println(jo);
    
    } finally {
        out.close();
    }
    Tip: To reformat your code, right-click within the editor and choose Format.
  7. Use the IDE's hints to add necessary import statements. These are:
    import dojo.org.json.JSONException;
    import dojo.org.json.JSONObject;
    and
    import java.util.logging.Level;
    import java.util.logging.Logger;
  8. Click the Run Main Project ( Run Main Project button ) button in the IDE's toolbar to run the project.

    The browser opens to display the welcome page (dojoDemo.html), and you can see that the Dojo Tree widget is displaying data from the ArrayList properly, as in the screenshot above.


Additional Tasks

 

Step 1: Examining communication with the HTTP Client Monitor

Let's examine the data that is being passed between the client and server. To do so, we can use the JavaScript Debugger's HTTP Client Monitor.

  1. Open the HTTP Client Monitor by choosing Window > Debugging > HTTP Client Monitor from the IDE's main menu.
  2. Before running the debugger on the project, specify that a JavaScript debugger session be created. To do so, open the debugger options in the Project Properties window.

    In the Projects window, right-click the project node and choose Properties. Then, in the Project Properties window, select the Debug category.
  3. Deselect the Java debugger option and select the JavaScript debugger option. (If you are not using Internet Explorer, the Firefox option is selected by default).
    Project Properties Debug window
  4. Click OK to save changes and exit the Project Properties window.
  5. Run the debugger by pressing the Debug Main Project button ( Debug main project button ) in the IDE's toolbar.

    If you are running the IDE's JavaScript debugger for the first time, the IDE detects whether you have the Firebug add-on and NetBeans Firefox extension installed in Firefox. If these have not been installed, the IDE attempts to install them.
    Dialog box
    Warning: If you see this dialog, shut down Firefox, then click OK. If not, the browser cannot load with the add-on and extension activated, and you will need to restart the browser manually, then rerun the debugger.

    A debugging session is initiated in the IDE, and the Dojo Tree example opens again in the browser.
  6. Double-click the HTTP Client Monitor tab to maximize it in the editor. Here you see all requests and responses passed between the client and server.

    When you select a request record in the top pane of the monitor, all request and response details are displayed in the lower panes.
  7. To view the JSON data returned to the client, toggle the All filter button located along the top of the HTTP Client Monitor. (The monitor opens by default displaying all message types. By clicking the All button, you are toggling the filter to display no messages.)
  8. Click the XHR filter button. XHR represents XMLHttpRequst and displays all messages being passed using an XMLHttpRequest object.

    Here you can see the request made for /tribeservlet.
    XHR requests displayed in HTTP Client Monitor
    As we know from the deployment descriptor (web.xml), the application handles requests for /tribeservlet using the TribeServlet.
  9. Click the /tribeservlet request record to select it. Then in the HTTP Response pane, note that the content type is set to JSON format, as we specified earlier when creating the servlet.
    Response details displayed in HTTP Client Monitor
  10. Now click the Body tab in the HTTP Response pane. Here you see the raw JSON content that was included in the response message.
    Response body details displayed in HTTP Client Monitor
  11. Click the Finish Debugger Session ( Finish Debugger Session button ) button to terminate the session.

Step 2: Modifying the project to respond with a static JSON file

It is also possible to set the TribeServlet to respond to incoming requests with a static JSON file. This might be a preferable approach when prototyping. Details follow.

  1. Create an empty JSON file in your project. Click the New File icon in the upper left corner of the IDE.
  2. In the New File wizard, select the Web category, then select JSON File.
    New File wizard
  3. Click Next, and in the Name and Location panel, type in tribeOutput as the file name, then type in web in the Folder text field.
  4. Click Finish. The new file opens in the editor.
  5. For sample data, let's use the example displayed in the Javadoc for TribeDataManager.getIndiansAsJSONObject(), which we looked at earlier.

    Switch to the TribeDataManager class in the editor.

    Tip: Press Ctrl-Tab and select the class from a list of open files.
  6. Place your cursor on the getIndiansAsJSONObject() method, and if it is not already opened, open the Javadoc window (Window > Other > Javadoc). The documentation for getIndiansAsJSONObject() displays in the Javadoc window.
  7. Copy (Ctrl-C; ⌘-C on Mac) the contents of the example. This is:
    {
      "identifier": "name",
      "items": [
          {
              "children": [
                  {"_reference": "Subarctic"},
                  {"_reference": "Arctic"}
              ],
              "name": "Alaska Natives",
              "type": "region"
          },
          {
              "children": [{"_reference": "Northern Athabaskan"}],
              "name": "Subarctic",
              "type": "category"
          },
          {
              "children": [{"_reference": "Eskimo-Aleut"}],
              "name": "Arctic",
              "type": "category"
          },
          {
              "name": "Eskimo-Aleut",
              "type": "tribe"
          },
          {
              "name": "Northern Athabaskan",
              "type": "tribe"
          }
      ],
      "label": "name"
    }
    You can see by examining the example that it only contains data for the "Alaska Natives" region.
  8. Paste the contents into the new tribeOutput.json file that you created. (The file should then contain only the pasted contents; any default content should be overwritten when pasting in.)
  9. Switch to the TribeServlet in the editor.

    We know that the Tree in dojoDemo.html uses the GET method when sending requests. Recall that this was indicated when we opened the HTTP Client Monitor earlier.
  10. Examine TribeServlet's doGet() method. (You may need to click a plus icon ( Code fold icon ) in the editor's left margin to view the method.)

    Note that the doGet() method simply calls the processRequest() method.
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
    Instead of calling the processRequest() method, let's use a RequestDispatcher to forward the response to the new tribeOutput.json file.
  11. Modify the doGet() method as follows.
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        RequestDispatcher dispatcher = request.getRequestDispatcher("tribeOutput.json");
        if (dispatcher != null)
            dispatcher.forward(request, response);
    }
    Note: Import the RequestDispatcher into the servlet. You can do this by clicking the suggestion icon ( Suggestion icon ) that displays in the left margin of the editor. When you choose 'Add import for javax.servlet.RequestDispatcher', the following line is added to the top of the class:
    import javax.servlet.RequestDispatcher;
  12. Run the project again and you can see that the data output in the Tree is limited to the contents specified in the tribeOutput.json file.
    Browser display using static JSON file

Step 3: Applying different Dojo themes

You can change the visual display of the Tree (and any other Dojo components included in your page). To do so, you only need to link to the CSS file of whatever theme you prefer, and add the theme's class name to the page.

Recall that Dijit provides three sample themes, and that we already added import statements for all of these.

Currently the Tree displays using the nihilo theme. You can experiment with the other themes by replacing the theme name in the body element with the theme you prefer.

For example, to view how the Tree looks with the tundra theme, replace the theme name you are currently using ("nihilo") with ("tundra").

<body class="tundra">
Run the project again and you will see the results.
Browser display using tundra theme

Summary

 

This exercise has demonstrated how it is possible to work with the bundled Dojo toolkit inside NetBeans IDE, and manage JSON communication between a Dojo Tree widget and Java ArrayList.

It has introduced you to the freely accessible Java JSON classes that are provided by json.org, and has also shown how to use the IDE's HTTP Client Monitor to examine message details between the client and server.

 

Back to top
Next exercise