Sunday, February 22, 2015

Making an Asynchronous JavaScript and XML (AJAX) call to a servlet from a Java Server Page.

Now, let me start by saying that this post is not specific to WebSphere Application Server, but I just recently was working on a project where we were deploying in a z/OS WebSphere Application Server cell....and had the need for an asynchronous call from a Java Server Page using JavaScript....so I thought I would detail how it was done on this blog.

What I was doing in this particular application was reading data from a VSAM file, and letting the users update, delete, modify...or add new records.  These records were very large records with a lot of individual fields to be updated. One of the fields was actually a reference to another record...and the users want the business name of the record displayed on the Java Server Page they were currently working on.  Instead of sending the entire form to a servlet just to get this data and then to repopulate the JSP with all of the data they had already entered, I decided to make this an AJAX call to a servlet...just to get this specific data field and display it on the currently active JSP.

The idea behind an AJAX call is that the call is made from the JSP to some javascript, and then off to a servlet, where some work is done and then the return area is sent back, all while staying on on the same page and letting the user keep working while the call is made.

This is a very simplistic example of a JSP, making an "onClick" call to a Java Script (AjaxJS.js), that sets up an AJAX call to a Java Servlet (AjaxServlet), and then having the Java Script display the return data in the "span id" testReply on the Java Server Page.

This servlet has an input field called "testVAR", where a user can enter 6 numeric characters.  In our instance...if the enter 123456 or 234567 they will get Customer #1 or #2.  If they enter any other 6 numeric values....they will get "Customer not found.".  Any other input will have a pop up box tell them that 6 numeric values must be entered.

When the "Validate" button is clicked.....off we go to the Java Script...AjaxJS.js (see below)

Sample Java Server Page:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="/AjaxTesting/AjaxJS.js"></script>
</head>
<body>
<form NAME=theForm METHOD="post" ACTION="/AjaxTesting/AjaxServlet" >
<P>
<PRE>
Jay Lang
Distributed Computing professionals inc.
jay@tpmq-experts.com

This is a test jsp that will demonstrate an AJAX (Asynchronous JavaScript and XML) call to a servlet
without send the form from the jsp to the WebSphere Application Server.  The call is made and data is
retrieved, while the form remains in tact.

For this testing, 6 numerics need to be input and the results will be retrieved.

  123456 will get "Customer #1"
  234567 will get "Customer #2"
  any other 6 numerics will return "Customer not found."
</PRE>
</P>
<table>
  <tr>
  <td><b>Test Ajax:&nbsp;</b> <input TYPE="text"  NAME="testVAR" ID="testVAR" SIZE="6" MAXLENGTH="6"><button type="button" onClick="getVarAjax()">Validate</button>&nbsp;&nbsp;&nbsp;<font color="red" size="2"><span id="testReply"></span></font></td>
  </tr>
</table>
  </form>
</body>
</html>

So the validate button has been clicked, and we are now in the Java Script below.  We blank out a msg variable and assign the variable "tv" that value of what the user entered in the text box. Then we set-up a url to the servlet, "AjaxServlet" preparing the Selection as getAjaxVar and also sending in the "tv" variable value.

If "tv" has a value...and it is 6 numerics, we will set-up and ActiveXObject and open a URL to call the AjaxServlet.

Now the call to the servlet has been made....so we will check the readyState and the status...and if they are good, we will set the document element "testReply" to the responseText we got back from the servlet.

So now, on to the servlet code.

Sample Java Script:

function getVarAjax() 
{
    var msg = "";
    var tv = theForm.testVAR.value;
    var xmlhttp;
    var url = "/AjaxTesting/AjaxServlet?Selection=getAjaxVar&testVAR="+tv;
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

    if(tv == "")
    {
     ;
    }
    else if(tv.match(/^\d{6}$/)) 
    {
     xmlhttp.open("POST",url,true);
 
     xmlhttp.onreadystatechange = function() 
     {
     if(xmlhttp.readyState == 4)
     {
      if(xmlhttp.status == 200)
      {
       document.getElementById("testReply").innerHTML = xmlhttp.responseText; 
      } 
     }
       }
    xmlhttp.send();
   }
   else
   {
    msg="Test VAR # must be 6 numerics";    
   }
    
   if(msg != "")
   {
    alert(msg);
   }
} // end of getVarAjax

In the  servlet, we set the function value to what the "Selection" set in the servlet string was, and if it is "getAjaxVar", we will assign the variable "inKey" to the "testVAR" value sent in on the servlet call string.

If the inKey value is "123456" we will set the replyData to "Customer #1"...if the inKey value is "234567" we will set the replyData to "Customer #2"...if any other 6 numbers...we will set the replyData to "Customer not found."

Now we prepare a response, setting the header fields and the content type, and then performing an out.println, flush and close of our replyData.

Sample Servlet:

package dcp.ajax;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class AjaxServlet
 */
public class AjaxServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
         
  public AjaxServlet() {
        super();
    }

  protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {

      String function = request.getParameter("Selection");
      String inKey = request.getParameter("testVAR");

      if(function.compareTo("getAjaxVar") == 0)
      {
       StringBuffer replyData = new StringBuffer("");  
       try
       {
        if(inKey.compareTo("123456")==0)
           replyData.append("Customer #1");
        else if(inKey.compareTo("234567")==0)
           replyData.append("Customer #2");
        else
           replyData.append("Customer not found.");
       }
       catch(Exception e)
       {
        // Here you would take the appropriate action based on your needs..
       }

       response.setHeader("Cache-Control", "no-cache");
       response.setHeader("Pragma", "no-cache");
       response.setContentType("text/html");
       PrintWriter out = response.getWriter();
       out.println(replyData.toString());
       out.flush();
       out.close();
    } // end of if
   }


  protected void doPost(HttpServletRequest request, HttpServletResponse response)         throws ServletException, IOException {
        doGet(request, response);
}

} // end of servlet


Screen Shots:

The initial JSP....waiting for some input.


The user has entered "123456" and has clicked the Validate button. You can see the return area in red..."Customer #1"























The user has entered "234567" and has clicked the Validate button. You can see the return area in red..."Customer #2"



The user has entered "345678" and has clicked the Validate button. You can see the return area in red..."Customer not found."



















Give yourself some flexibility in your designs by using Ajax calls to communicate with the server and servlets while maintaining your position and current values in your Java server pages.

If you have trouble implementing an Ajax call...don't hesitate to contact me.

Jay Lang - jay@tpmq-experts.com

Happy programming!!!!