Part VI: Appendixes


Integrating AJAX with the Mini HR Application

Following is the list of steps that you follow to integrate AJAX with the Mini HR application:

  1. Add a method called getEmployeeCount( ) to the EmployeeSearchService class. This method will get the current employee count.

  2. Create a CountAction class.

  3. Configure the CountAction class in the struts-config.xml file.

  4. Update search.jsp to use AJAX to retrieve the current employee count and display it.

  5. Recompile, repackage, and run the updated application.

The following sections walk you through each step of the process in detail.

Add getEmployeeCount( ) to EmployeeSearchService

The first step in updating the Mini HR application to use AJAX is to add a new method to the EmployeeSearchService class for obtaining the current employee count. This new method, getEmployeeCount( ), will become part of the existing Model layer of the application and be called by an action. The new getEmployeeCount( ) method is shown next:

// Calculate count of employees. public int getEmployeeCount() {   return employees.length; }

As you can see, the method is very simple. If EmployeeSearchService were a more sophisticated implementation that interfaced with a dynamic data source, the getEmployeeCount( ) method would make a query to obtain the count instead of returning the static count in the current implementation.

Following is the updated EmployeeSearchService class in its entirety; the new method is shown in bold:

package com.jamesholmes.minihr;     import java.util.ArrayList;     public class EmployeeSearchService {   /* Hard-coded sample data. Normally this would come from a real data      source such as a database. */   private static Employee[] employees =   {     new Employee("Bob Davidson", "123-45-6789"),     new Employee("Mary Williams", "987-65-4321"),     new Employee("Jim Smith", "111-11-1111"),     new Employee("Beverly Harris", "222-22-2222"),     new Employee("Thomas Frank", "333-33-3333"),     new Employee("Jim Davidson", "444-44-4444")   };       // Search for employees by name.   public ArrayList searchByName(String name) {     ArrayList resultList = new ArrayList();         for (int i = 0; i < employees.length; i++) {       if (employees[i].getName().toUpperCase().indexOf(name.toUpperCase()) != -1)       {         resultList.add(employees[i]);       }     }         return resultList;   }       // Search for employee by social security number.   public ArrayList searchBySsNum(String ssNum) {     ArrayList resultList = new ArrayList();         for (int i = 0; i < employees.length; i++) {       if (employees[i].getSsNum().equals(ssNum)) {         resultList.add(employees[i]);       }     }         return resultList;   }       // Calculate count of employees.   public int getEmployeeCount() {     return employees.length;   } }

Create a CountAction Class

Now that the new getEmployeeCount( ) method has been added to EmployeeSearchService, a CountAction class must be created for calling the new method and returning its output to a browser via an AJAX call. CountAction is like any other action in that it subclasses the Struts Action class and provides an implementation for the execute( ) method. It differs, however, in an important way. Instead of returning an ActionForward from the execute( ) method, it returns null and a response is written directly to the HTTP response stream. The CountAction class is shown next:

package com.jamesholmes.minihr;     import java.io.PrintWriter;     import java.util.ArrayList;     import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping;     public final class CountAction extends Action {   public ActionForward execute(ActionMapping mapping,     ActionForm form,     HttpServletRequest request,     HttpServletResponse response)     throws Exception   {     EmployeeSearchService service = new EmployeeSearchService();         // Retrieve employee count.     int employeeCount = service.getEmployeeCount();         // Write employee count to HTTP response.     PrintWriter out = response.getWriter();     out.print(employeeCount);         // Return null to inform the controller servlet     // that the HTTP response has been handled.     return null;   } }

As you can see, this action is straightforward; it instantiates the EmployeeSearchService service and retrieves the current employee count. The count is then written directly to the HTTP response so that it can be read by an AJAX call. Finally, null is returned to indicate to the Struts controller servlet that the response has been generated and no further processing is required.

Configure the CountAction Class in the struts-config.xml File

After you have created the new CountAction class, you must configure an action mapping for it in Mini HR's Struts configuration file, struts-config.xml, as shown here:

<action path="/count"         type="com.jamesholmes.minihr.CountAction"> </action>

You'll notice that this action mapping is less detailed than the mapping for SearchAction. Because no Form Bean is required or used, none of the action tag's attributes for configuring a Form Bean are specified.

The following code shows the updated Struts configuration file for Mini HR in its entirety. The section that has changed is shown in bold.

<?xml version="1.0"?>     <!DOCTYPE struts-config PUBLIC   "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"   "http://struts.apache.org/dtds/struts-config_1_3.dtd">     <struts-config>       <!-- Form Beans Configuration -->   <form-beans>     <form-bean name="searchForm"                type="com.jamesholmes.minihr.SearchForm"/>   </form-beans>       <!-- Global Forwards Configuration -->   <global-forwards>     <forward name="search" path="/search.jsp"/>   </global-forwards>       <!-- Action Mappings Configuration -->   <action-mappings>     <action path="/search"             type="com.jamesholmes.minihr.SearchAction"             name="searchForm"             scope="request"             validate="true"             input="/search.jsp">     </action>     <action path="/count"             type="com.jamesholmes.minihr.CountAction">     </action>   </action-mappings>       <!-- Message Resources Configuration -->   <message-resources     parameter="com.jamesholmes.minihr.MessageResources"/>     </struts-config>

Update search.jsp to Use AJAX

The next step is to update the application's original search.jsp file to use AJAX for retrieving a current employee count and displaying the count. There are a few changes that have to be made in order to do this. The following list outlines each of the changes.

  • Add JavaScript for performing the AJAX call to the CountAction and for updating the page's HTML.

  • Add a section of HTML inside a <span> tag that will be updated by the JavaScript.

  • Add an HTML button that invokes the JavaScript that makes the AJAX call and updates the page's HTML.

Following is the updated search.jsp page. Each section of the file that is new or has been changed is shown in bold.

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>     <html>     <head> <title>ABC, Inc. Human Resources Portal - Employee Search</title> <script language="JavaScript">   var request;       function getCount() {     var url = "/MiniHr/count.do";         // Perform the AJAX request using a non-IE browser.     if (window.XMLHttpRequest) {       request = new XMLHttpRequest();           // Register callback function that will be called when       // the response is generated from the server.       request.onreadystatechange = updateCount;           try {       request.open("GET", url, true);       } catch (e) {          alert("Unable to connect to server to retrieve count.");       }           request.send(null);     // Perform the AJAX request using an IE browser.     } else if (window.ActiveXObject) {       request = new ActiveXObject("Microsoft.XMLHTTP");           if (request) {         // Register callback function that will be called when         // the response is generated from the server.         request.onreadystatechange = updateCount;             request.open("GET", url, true);         request.send();       }     }   }       // Callback function to update page with count retrieved from server.   function updateCount() {     if (request.readyState == 4) {       if (request.status == 200) {         var count = request.responseText;             document.getElementById('employeeCount').innerHTML = count;       } else {         alert("Unable to retrieve count from server.");       }     }   } </script> </head> <body>     <font size="+1"> ABC, Inc. Human Resources Portal - Employee Search </font><br> <hr width="100%" noshade="true">     <html:errors/>     <html:form action="/search">     <table> <tr> <td align="right">Current Employee Count:</td> <td>   <i><span >?</span></i>   <input type="button" value="Get Count" onclick="getCount();"> </td> </tr> <tr> <td colspan="2"><br></td> </tr> <tr> <td align="right"><bean:message key="label.search.name"/>:</td> <td><html:text property="name"/></td> </tr> <tr> <td></td> <td>-- or --</td> </tr> <tr> <td align="right"><bean:message key="label.search.ssNum"/>:</td> <td><html:text property="ssNum"/> (xxx-xx-xxxx)</td> </tr> <tr> <td></td> <td><html:submit/></td> </tr> </table>     </html:form>     <logic:present name="searchForm" property="results">     <hr width="100%" size="1" noshade="true">     <bean:size  name="searchForm" property="results"/> <logic:equal name="size" value="0"> <center><font color="red"><b>No Employees Found</b></font></center> </logic:equal>     <logic:greaterThan name="size" value="0"> <table border="1"> <tr> <th>Name</th>     <th>Social Security Number</th> </tr> <logic:iterate  name="searchForm" property="results"> <tr> <td><bean:write name="result" property="name"/></td> <td><bean:write name="result" property="ssNum"/></td> </tr> </logic:iterate> </table> </logic:greaterThan>     </logic:present>     </body> <html>

As you can see, there are two new sections of code in the JSP. The first section contains the JavaScript code that performs the AJAX request to CountAction. CountAction returns a count of the current number of employees directly to the HTTP response stream, which is read by the JavaScript code. The JavaScript code then updates the count section of the page with the value returned from CountAction. The second new section of code added to the JSP is the section that displays the current employee count. Notice that <span> tags are used to encapsulate the count value. When using AJAX, <span> tags are used to mark specific sections of content for easy updating. The JavaScript code that updates the page will reference the encapsulated content by the name specified with the surrounding <span> tags.

Recompile, Repackage, and Run the Updated Application

Because you added the getEmployeeCount( ) method to EmployeeSearchService and created the CountAction class, you need to recompile and repackage the Mini HR application before you run it. Assuming that you've made modifications to the original Mini HR application and it was set up in the c:\java\MiniHR directory (as described in Chapter 2), you can run the build.bat batch file or the build.xml Ant script file to recompile the application.

After recompiling Mini HR, you need to repackage it using the following command line:

jar cf MiniHR.war *

This command should also be run from the directory where you have set up the Mini HR application (e.g., c:\java\MiniHR).

Similar to the way you ran Mini HR the first time, you now need to place the new MiniHR.war file that you just created into Tomcat's webapps directory, delete the webapps/MiniHR directory, and start Tomcat. As before, to access the Mini HR application, point your browser to http://localhost:8080/MiniHR/. Once you have the updated Mini HR running, you will see the new "Current Employee Count" section on the search page as illustrated in Figure 23-1. Try clicking the "Get Count" button. You will notice that the count on the page updated without the entire page refreshing as illustrated in Figure 23-2. This is a basic usage of AJAX, but it illustrates the core steps involved in using this powerful technique.

image from book
Figure 23-1: The Current Employee Count section on the Employee Search page

image from book
Figure 23-2: Updated Employee Count on the Employee Search page



Struts. The Complete Reference
Struts: The Complete Reference, 2nd Edition
ISBN: 0072263865
EAN: 2147483647
Year: 2004
Pages: 165
Authors: James Holmes

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net