Wednesday, May 16th, 2007...4:27 pm

Using Protototype AJAX & JSON with J2EE and Struts

Jump to Comments

We don't always get to use the latest greatest web framework, but just because you're using a crusty old dinosaur J2EE XML framework from the pits of hell, doesn't mean you can't make girls cry with your AJAX/JSON skills.

This tutorial will show how to use prototype to return JSON data to your jsp.

Prerequisites

This tutorial will be Struts-centric, but really is adaptable to any Java/J2EE platform. I'm not going to include any DB Layer specific code since that seems to change so much, but you should know how to take a query result and put it in a hash map.

The Goal

Create a Struts Action class that queries the database and returns the result in a JSON object back to a JSP with as little fuss as possible.

The JSP

In this example, I want to populate a text box in my form with data returned from an AJAX request in the background. For example, sometimes you want to pull out a person's name based on some internal ID. This saves our user from having to type it in by hand and also eliminates spelling mistakes.

So let's assume we have a text box where the user would type in the id as well as a text box where they would type the full name, the code would look something like this

<input type="text" id="theId" name="theId"/>
<input type="text" id="fullName" name="fullName"/>

We'll then have a javascript function that uses prototype to create an AJAX request that hits a struts action to to the database look up, then populates the fullName text box with the fullName property from the returned JSON object.

function lookup()
{
  new Ajax.Request('<html:rewrite page="/util/namelookup.do"/>', {
   parameters: {theId: $('theId').value},
    onSuccess: function(transport, json) {
     if(json.executeError)
      {
      alert(json.executeError);
      }
      else
      {
      $('fullName').value = json.fullName;
      }
   
    }
});

The Java

Our goal here is to do some work and put that work in a JSON object, for me the easiest way is to just query the DB and throw the results into a hashmap or java bean. To do the JSON lifting in this example I use the open source json-lib. If an error occurs we'll put error text in a key in the JSON object called executeError so that we can display that in our javascript.

public class NameLookupAction extends Action
{

  public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response)
    throws Exception
  {

    String theId = request.getParameter("theId");

    try
    {

      //Do your database work here to grab the name and populate our HashMap hm
      //In this example I'll just hard-code the name though.

       HashMap hm = new HashMap();
       hm.put("fullName","Joe Blow");

        //each key from our hash map becomes a key in our JSON object
        JSONObject json = JSONObject.fromObject(hm);

        //Plop it in the header so prototype can grab it.
        response.setHeader("X-JSON", json.toString());

      }
    }
    catch (Exception e)
    {
      HashMap hm = new HashMap();
      hm.put("executeError", "Couldn't find the Full Name because an error occured.");

      JSONObject json = JSONObject.fromObject(hm);

      response.setHeader("X-JSON", json.toString());

    }

    return mapping.findForward("success");

  }

So that's all there is to it, as you can see it's pretty simple stuff but quite powerful. I like to create utility classes that return a whole bunch of info from a query, they're quite handy to have around to quickly display information in your web app without having to do a lot of leg work of new windows and new jsp pages, etc.

Extra struts-config.xml Stuff

If you're using struts you need to forward to a jsp of some sort, this is just going to be an empty JSP page, the JSON info is stored in the response header, anyway here's what your struts-config.xml entry might look like for this action.

<action path="/util/namelookup" scope="request" type="com.yourcompany.NameLookupAction" validate="false">
      <forward name="success" path="/WEB-INF/jsp/ajax/empty.jsp"/>
  </action>

2 Comments

Leave a Reply