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>

7 Comments

  • Nice tutorial. Thanks very much.
    I wonder if there are more such examples that show the use of JSON with J2EE components

  • Hi,

    It will be nice if there are more exapmles on JSON.

  • seyhan basmacı
    March 3rd, 2010 at 4:13 am

    for the last statement (return mapping.findForward("success");) , you can just return null to inform struts about response already sent to client.

    return null;

    no need for empty.jsp and struts-config.xml definition.

  • Help support the great nation of Japan from the earthquake by performing a small donation!

  • Hi,

    can you please put a complete code, I would like to try it, run it .
    thanks

  • Complete code

    JSP Page
    -----------

    JSP Page

    function lookup() {
    new Ajax.Request('namelookup.do', {
    parameters: {theId: $('theId').value},
    onSuccess: function(transport, json) {
    if(json.executeError) {
    alert(json.executeError);
    }
    else {
    $('fullName').value = json.fullName;
    }
    }
    });
    }

    Hello World!

    Action Class
    ----------------
    public class NameLookupAction extends org.apache.struts.action.Action {

    /* forward name="success" path="" */
    private static final String SUCCESS = "success";

    /**
    * This is the action called from the Struts framework.
    * @param mapping The ActionMapping used to select this instance.
    * @param form The optional ActionForm bean for this request.
    * @param request The HTTP Request we are processing.
    * @param response The HTTP Response we are processing.
    * @throws java.lang.Exception
    * @return
    */
    @Override
    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 null;
    }
    }

    struts-config.xml
    ----------------------

  • Seems JSP and struts-config.xml page codes are not showing properly
    JSP Page
    -----------
    <%--

    JSP Page

    function lookup() {
    new Ajax.Request('namelookup.do', {
    parameters: {theId: $('theId').value},
    onSuccess: function(transport, json) {
    if(json.executeError) {
    alert(json.executeError);
    }
    else {
    $('fullName').value = json.fullName;
    }
    }
    });
    }

    Hello World!

    --%>

    struts-config.xml
    ---------------------
    <!-- -->

Leave a Reply