serving the solutions day and night

Pages

Tuesday, June 8, 2010

AJAX, Send/Receive XML Request/Response using JAVA - Part 2

I blogged What Ajax is and higher-level codes, let's put all together and example for send XML request/response using Ajax enabled Java application.

Sequence Diagram for AJAX Using JAVA

Here i explain 2 application of XML.
1)To send a request from a Ajax to a Java servlet in XML format
2)To receive a response from a Java servlet in Ajax in XML format


GetXmlHttpObject() function used to created and configured a XMLHttpRequest object.
function GetXmlHttpObject()
{
  var objXMLHttp=null;
  if (window.XMLHttpRequest) objXMLHttp=new XMLHttpRequest();
  else if (window.ActiveXObject) objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP");
  return objXMLHttp;
}

createXML() function is used to create a XML document, just stringing together the text. value pairs turn into XML elements, where the element <name> is the name of the pair, and the content of the element is the value, like <coinid>123</coinid>.
function createXML( root, nodes )
{
  var xml = "";
  if( root )
    xml += "<" + root + ">";
  for( theNode in nodes )
    xml += "<" + theNode + ">" + nodes[theNode] + "";
  if( root )
    xml += "";
  return xml;
}

Much of the below statements are self-explanatory. SingleIUD() function called from form component or event methods. When the statement xmlCoin.send(xml); is reached, the call will be made. When this function is called on the XMLHttpRequest object, the call to the URL that was set during the configuration of the object is called. encodeHtmlAttribute(desc) function used to encoded the special characters.
var xmlCoin;
function SingleIUD()
{
  //The value from the HTML page.
  var coinid = document.getElementById('coinid').value;
  var dml = document.getElementById('dml').value;
  var amount = document.getElementById('amount').value;
  var desc = document.getElementById('desc').value;
  desc = encodeHtmlAttribute(desc);

  //Creates a parameters array for xml.
  var params = {};
  params["coinid"] = coinid;
  params["dml"] = dml;
  params["amount"] = amount;
  params["desc"] = desc;

  //Pass array to createXML function, to create xml document.
  xml = createXML("coin",params);

  //xmlCoin creates an XMLHttpRequest object and calls the open function on the object.
  xmlCoin=GetXmlHttpObject()
  if (xmlCoin==null)
  {
    alert ("Browser does not support HTTP Request");
    return;
  }

  //url is either jsp or servlet filname.
  var url = "../ajCoinDML";
  xmlCoin.open("POST",url,true)
  xmlCoin.onreadystatechange=getSingleIUD;

  //An HTTP POST requires a Content-Type header to be set on the XMLHttpRequest object
  xmlCoin.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

  //encodeURIComponent() function used to content is encoded properly and that special characters are encoded correctly to be passed in an HTTP request.
  xmlCoin.send(encodeURIComponent(xml));
}

The XMLHttpRequest object calls the getSingleIUD() callback function and processes the result. The XMLHttpRequest object was configured to call the getSingleIUD() function when there are changes to the readyState of the XMLHttpRequest object. The call to the ajCoinDML.java servlet was made and the readyState is 4, the XMLHttpRequest call is complete and successful.
function getSingleIUD()
{
  if (xmlCoin.readyState==4 || xmlCoin.readyState=="complete")
  {
    var xml = xmlCoin.responseXML;
    var coinid = (xml.getElementsByTagName("coinid")[0]).childNodes[0].nodeValue;
    var dml = (xml.getElementsByTagName("dml")[0]).childNodes[0].nodeValue;
    var error = (xml.getElementsByTagName("error")[0]).childNodes[0].nodeValue;
    //Do Something
  }
}

The request is processed by the ajCoinDML.java servlet. The Java API for XML Processing (JAXP) is an API, but it is called an abstraction layer. JAXP makes it easier to use DOM and SAX. In the below ajCoinDML.java servlet example, i used DOM with JAXP. Because i like DOM compare to SAX, DOM has an in-memory tree structure, provide to modify an XML document. The org.w3c.dom class represents an XML document and is made up of DOM nodes that represent the elements, attributes, and other XML constructs.
import java.io.*;

import javax.servlet.ServletException;
import javax.servlet.http.*;

//JAXP
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

//DOM
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class ajCoinDML extends HttpServlet
{
  private String NodeValue(Element elLists, String sTagName)
  {
    String sNodeValue = "";
    NodeList nlXml = elLists.getElementsBysTagName(sTagName);
    Element elXml = (Element)nlXml.item(0);
    NodeList nlXmlValue = elXml.getChildNodes();
    if (((Node)nlXmlValue.item(0))!=null)
      sNodeValue = ((Node)nlXmlValue.item(0)).getNodeValue().trim();
    return sNodeValue;
  }

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

  public void doPost (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
  {
    String sError = "";
    PrintWriter pwOut = response.getWriter();

    try
    {
      //Reading AJAX XML document request
      java.util.Enumeration enuParams = request.getParameterNames();
      String sParamName = (String) enuParams.nextElement();

      //DocumentBuilderFactory is configured to handle validation and namespaces
      DocumentBuilderFactory dbfBuilderFactory = DocumentBuilderFactory.newInstance();

      //DocumentBuilder is retrieved from the factory
      DocumentBuilder dbBuilder = dbfBuilderFactory.newDocumentBuilder();
      Document docXML = dbBuilder.parse(new InputSource(new StringReader(sParamName)));
      docXML.getDocumentElement ().normalize ();

      NodeList nlCoins = docXML.getElementsBysTagName("coin");
      Node nodeCoins;
      Element elLists;

      int iRow=0;
      nodeCoins = nlCoins.item(iRow);
      elLists = (Element)nodeCoins;

      //Parsing XML document request using DOM
      String sDml = NodeValue(elLists, "dml");
      int iCoinID = Integer.parseInt(NodeValue(elLists, "coinid")));
      float fAmount = Float.parseFloat(NodeValue(elLists, "amount")));
      String sDesc = NodeValue(elLists, "desc");

      sError = //Do Insert, Update or Delte;

    }
    catch (Exception e)
    {
      sError = e.toString();
    }

    //Creating response XML document request using DOM
    StringBuffer sfXml = new StringBuffer();
    response.setContentType("text/xml");
    sfXml.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
    sfXml.append("<response>\n");
    sfXml.append("\t<coinid>" + getCoinID() + "</coinid>\n");
    sfXml.append("\t<error>" + sError + "</error>\n");
    sfXml.append("</response>\n");
    pwOut.println(sfXml.toString());
    pwOut.flush();
    pwOut.close();
  }
}

The ajCoinDML.java servlet returns an XML document containing the results. Following a successful request, the object returns of the XML document that was retrieved from the ajCoinDML.java servlet using the xmlCoin.responseXML;

<response>
  <coinid></coinid>
  <error></error>
</response>

The statment (xml.getElementsByTagName("coinid")[0]).childNodes[0].nodeValue; is used to parse XML response.

Ajax (Asynchronous JavaScript and XML) - Part 1
AJAX, Send XML Request/Response Using PHP XML DOM - Part 3

1 comment:

Anonymous said...

1. Where is ajCoinDML.java kept? Will the XMLHttpRequest able to open it from the src folder and the jsp will be in the webcontent folder. Is any mapping required for that?
2. When i try to access the xmlhttprequest data in Servlet through request.getParameter. it gives me null. I can retrieve the form data through request.getParameter("string") but not the xmlhttprequest string :(