Skip to main content

Program with XML for DB2, Part 3: Program with XML in the client

Hardeep Singh (hardeep@us.ibm.com), Architect Advanced Technologies, IBM, Software Group
Hardeep Singh is a member of the advanced technologies group. He is the architect for DB2 XML tooling and XML migration. He has over 23 years of industry experience.

Summary:  Learn how to extend the XML model in order to create rich clients using XML data transferred from your application server. Discover how to use Dynamic HTML (DHTML) to present the XML, XPath to navigate the XML and the Document Object Model (DOM) to modify and serialize the XML back to the application server.

View more content in this series

Date:  16 Aug 2007
Level:  Intermediate
Activity:  809 views

Introduction

The increased popularity of Web 2.0 is due largely to the flexibility of the current generation of web browsers. These browsers use Ajax to communicate with the server to interchange XML data and then employ DHTML to navigate the XML and present it to the user. The browser capabilities enable them to be used as thick clients in a web based application.

These base technologies gave birth to a number of new technologies and initiatives to meet the growing popularity of Web 2.0. New helper libraries like Dojo and Sarissa have been created to make using XML less painful, and there has been increased support for Scalable Vector Graphics (SVG). Embeddable widgets like Google and Yahoo Maps, data syndicatoin and integration methodologies such as RSS and Atom feeds, and a new paradigm of developments using data mashups have all been developed to meet the growing demands of the Web 2.0 culture.

As Figure 1 illustrates, the common glue in all the technologies is XML. The XML in the feeds makes it possible to publish and ingest complex data structures over the web. DOM application programming interfaces (APIs) in DHTML and XPath support in Sarissa allow efficient navigation of the XML for reading and writing in the client.


Figure 1. Web oriented architecture
Web oriented architecture

Note : In the Web 2.0 world where data sources are viewed as feeds and services, database drivers are extended to support REST, FEED and SOAP calls. Once security implications have been resolved, you will be able to access database routines directly using SOAP or REST calls not only from an application server, but also from a web client, without having to create unnecessary mappings. In the next article, the author creates a sample SOAP driver for DB2®.


Leveraging the XML model in the client

Since many of the surrounding XML technologies are common to the application server and the browser, you can extend the XML data model seen in the first article to the client as well. In this article, learn how to extend the XML model in order to create rich clients using XML data transferred from the application servers. Discover how to use DHTML to present the XML, XPath to navigate the XML and the DOM to modify and serialize the XML back to the application server.

Similar to the DOM wrapper that you created in the application server, you will create a DOM wrapper for the client. This wrapper not only isolates the JavaScript visualization and business logic code from the DOM APIs, but also makes the code very similar to the Java ™code in the application server layer. To achieve this, you will use the open source library Sarissa that provides XPath APIs to the JavaScript code running in the browser. The wrapper code is available with this article (see downloads).

<script type="text/javascript" src="sarissa/sarissa.js"></script>
<script language="javascript" type="text/javascript" src="xmlparse.js"></script>


Scenario

The following sections build on the insurance examples created in the previous articles of this series (see Resources). The following functionality is provided by the web client.

1. Allow users to view and modify the first and last name in their profile.

2. Calculate the insurance rates for each item purchased based on the insurance provider the user selects.

It is important to note: The code in this and the previous articles is only for explanation purposes. Only parts that explain the relevance of the XML model are fully coded. The rest of the logic is pseudo-coded with the assumption that the reader can extrapolate the standard code expected for that functionality. The next article discusses a complete business scenario that will be fully coded.

Allow user to view and modify their name.

Retrieve the customer information from the application server and present it to the client for modifications.

Client JavaScript code

The profilediv is used to publish the HTML string created from the XML data to the user.

<div class="profilediv" id="profilediv"></div>


The customer ID (cid) is entered when the user logs into the site. This customer ID is passed to the getCustomerInfo function when the user selects Update profile in the client. The client sends an HTTP request to the server using the XMLHttpRequest API provided by the Sarissa library. As a part of the request, the callback function is also defined. This function, customerInfoCallback, is invoked when the response comes from the server. Listing 1 shows how to retrieve customer information:


Listing 1. Client requests customer information
<script>
function getCustomerInfo(cid)
{
var xmlhttpObj= new XMLHttpRequest();
var addr=hosturl+"?cmd= getuserprofile&msg="+cid;
var xmlhttpObj= new XMLHttpRequest();
xmlhttpObj.open('GET', addr, true);
xmlhttpObj.onreadystatechange = function() { customerInfoCallback(xmlhttpObj); };
 xmlhttpObj.send("");
 }

Application server Java code

Listing 2 shows what happens in the application server when it receives the clients HTTP request. The server first checks if the HTTP request was a POST or a GET and then, based on this information, retrieves the command and data values from the parameters of the HTTP call.


Listing 2. Application server retreives customer information
                public void service( HttpServletRequest _req, HttpServletResponse _res)
throws ServletException, IOException
{

String cmd, msgtext, returnvalue;

if(_req.getMethod().equalsIgnoreCase("POST"))
{
String message = getPostBody(_req.getReader());
 XMLParse msgxml=new XMLParse(message);
 cmd= msgxml.getValue("//request/@cmd");
msgtext= msgxml.toString("/request/*");
}
else
{
cmd= _req.getParameter("cmd");
msgtext= _req.getParameter("msg");
}

Since the command is to get the user's profile, the application server accesses the customer information from the database and returns it to the client. Listing 3 only shows the SQL statement necessary to get the information; it is expected that the reader already understands how to use the Java Database Connectivity (JDBC) APIs to connect to the database and get the query result.

Since the customer information is stored in the database as an XML document, you don't need to do any transformations to the data in order to return it to the client. Please note that the content type of the returned data is set to XML in the response HTTP header.


Listing 3. Application server's response
                if(cmd.equalsIgnoreCase("getuserprofile"))
{
//returnvalue= select CUSTXML from customer_table where customerid =msgtext
}
_res.setContentType("text/xml");
_res.getWriter().write(returnvalue);
 _res.setHeader("Cache-Control", "no-cache");

Client JavaScript code

When the client receives the response from the application server, the function defined in the callback event is invoked.

Listing 4 shows the request for the userinfo. Please note that the userinfo is declared as a global variable since it is modified when you send the updates made by the user to the first or last names.


Listing 4. Request for userinfo
                var userinfo=null;
function customerInfoCallback (xmlhttp)
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{

Since the returned value from the server is XML, you pass it directly to the constructor of your DOM wrapper.

userinfo= new xmlparse(xmlhttp.responseXML, false);

Next, you extract the first and last names from the XML using XPath.

var firstname = userinfo.getValue("/Customer/@firstname",null);
var lastname = userinfo.getValue("/Customer/@lastname",null);

Listing 5 shows how to use DHTML to create a graphical user interface (GUI) for the user name modification and insert it into to the div tag, profilediv, that you declared in your HTML page.


Listing 5. DHTML that creates a GUI
                var htmlstr="<table class='inputtable'><tr>";
htmlstr+='<td>firstname:</td><td><input id="fname" value="'+firstname+'"/></td>';
htmlstr+='<td>lastname:</td><td><input id="lname" value="'+lastname+'"/></td>';
htmlstr+='<tr><td/><td><input type="button" value="save"
onClick="javascript:updateCustomer()"/></td>';
htmlstr+='</tr></table>';
document.getElementById("profilediv").innerHTML=htmlstr;
}
}

Once you have done the modifications, click on the Save button to invoke the updateCustomer function. The DOM userinfo containing the customer information is updated with the user modifications. Here again, you use XPath to navigate to the data nodes that need to be modified.


Listing 6. use XPath to update customer information
                function updateCustomer()
{
var fname=document.getElementById("fname").value;
 var lname=document.getElementById("lname").value;
 userinfo.setValue("/Customer/@firstname",null,fname);
 userinfo.setValue("/Customer/@lastname",null,lname);

A new request is created and the updated DOM is serialized and appended to it. Listing 7 shows the request string then being sent (POST) to the server.

Note that since the message format is XML, the content type in the HTTP header of the request is set to XML.


Listing 7. Request string sent to the server
                var msg='<request cmd=" updateuserprofile">'+userinfo.toString("/")+'</request>';
var xmlhttpObj= new XMLHttpRequest();
xmlhttpObj.open('POST', hostname, true);
xmlhttpObj.onreadystatechange = function() { profileUpdated(xmlhttpObj); };
xmlhttpObj.setRequestHeader('content-type', 'text/xml');
xmlhttpObj.send(msg);
}

Application server Java code

The incoming customer XML data from the request is parsed using the DOM wrapper.

Since customerid is an attribute in the original customer profile that was sent to the client, there is no need to send an extra parameter for the customer ID in the request.

Listing 8 shows how to extract the customerid from the XML and use it to create an update SQL command for the database. The customer profile data from the HTTP request is passed as a parameter to the update statement; no modifications are needed.


Listing 8. Create an update SQL command
                else if(cmd.equalsIgnoreCase("updateuserprofile"))
{
XMLParse custxml=new XMLParse(msgtext);
String cid= custxml.getValue("/Customer/@customerid");
//update customer_table set custxml=? where customerid=cid
//stmt.setString(1,msgtext);
}

Notice the similarity in application code that is used to navigate the XML in both the client and the server. Also, note that the applicatoin server in both the HTTP requests acted simply as a go-between for the client and the database -- no data was manipulated in the interchange.

Calculate the insurance rates for items purchased

The user selects an insurance company from a drop down list that contains the names of all insurance carriers. The insurance company has a web service that can be queried to get the current insurance rates. The rate information is provided as an XML document and is used by the application to calculate the insurance on each item.

Client JavaScript code

The URL for the associated web service provided by that insurance company is also selected from the list. Since Ajax prevents URL redirection, you need to invoke the web service from the application server. You pass the URL in the request to the application server for calculating the insurance cost of each item purchased. Listing 9 shows tihs process:


Listing 9. Client selects URL
                function itemsPurchased(url,cid)
{
var msg='<request cmd="getPurchaseInfoWithInsurance"><data customerid="cid">
<![CDATA['+ url+']]></data></request>';

var xmlhttpObj= new XMLHttpRequest();
xmlhttpObj.open('POST', hostname, true);
xmlhttpObj.onreadystatechange = function() { temsPurchasedCallback (xmlhttpObj); };
xmlhttpObj.setRequestHeader('content-type', 'text/xml');
xmlhttpObj.send(msg);
}
}

Note : Since the URL might contain special characters, we have embedded it inside a CDATA section to prevent the request XML from becoming malformed.

Application server Java code

The request message is parsed using the DOM wrapper and the insurance URL is extracted from it. Listing 10 shows how the application uses this URL to make a call to the web service of the insurance provider to retrieve the XML document containing the insurance rates.


Listing 10. Application server retrieves insurance rates
                else if(cmd.equalsIgnoreCase("getPurchaseInfoWithInsurance"))
{
XMLParse dataxml=new XMLParse(msgtext);
String url= dataxml.toString("/data/text()");
String insurancestr=callWebServiceUsingHTTPClient(url);

Note : The insurance rate XML is defined in Part 2, in the section entitled "A more elaborate example." .

The customer ID is also extracted from the message and is used to query the database for information on the items purchased by the customer.

String cid= dataxml.getValue("/data/@customerid");

The rest of the business logic for creating the purchased item list is implemented in either of two ways:

  1. Make a call to the database stored procedure created in Part 2>Listing 6.
    // returnvalue = call customerItemsWithInsurance (cid, insurancestr);
    

  2. Code the logic in the application server using the code from the first article. Using the customerXML from Part 1: Listing 6 , loop through each item, calculate the insurance cost, and add it to the item information.

    Replace lines 9-11 in the original code with the following:



    Listing 11. Replacement for lines 9-11
                             XMLParse insurancexml=new XMLParse(insurancestr);
    customerXML.find("/Customer/Items/item",true);
    String currency= insurancexml.getValue("//rate/@currency");
    
    for(int i=0; customerXML.currentFind.getLength()>i;i++)
    {
    price = customerXML.getValue("@price",i));
    if(price>500) rate= insurancexml.getValue("//rate[@price=""]/@rate"));
    else If(price>100) rate= insurancexml.getValue("//rate[@price="500"]/@rate"));
    else rate= insurancexml.getValue("//rate[@price="100"]/@rate"));
    String iteminsurance="<insurance currency="+currency+ ">"+price*rate+"</insurance>"
    customerXML. appendElement(customerXML.createNode (iteminsurance),
    customerXML.getNode (null,i), false )
    }
    // returnvalue = customerXML.toString();
    

If you compare the above code to the query in the customerItemsWithInsurance stored procedure of Article 2, you will note that there is a lot of similarity between the two, especially in the XPaths that were used. This fact once again reinforces the advantage of using the XML model and the ease of pushing business logic into the database.

Also note the power of XPath expressions to search and navigate inside the hierarchical XML Data Model . Replicating this kind of search in an Object Data Model using java code would require a great deal of effort. Using XPath simplifies the process and allowes it to be done with a single string expression.

Client JavaScript code

The server response invokes the itemsPurchasedCallback function in which the returned XML data is parsed using the DOM wrapper. Listing 12 shows how to do this:


Listing 12. XML is parsed using the DOM wrapper
                function itemsPurchasedCallback (xmlhttp)
{

if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
var itemInfo= new xmlparse(xmlhttp.responseXML, false);

First extract the user name from the returned XML:


Listing 13. Extract user name
                var firstname = userinfo.getValue("/Customer/@firstname",null);
var lastname = userinfo.getValue("/Customer/@lastname",null);

var htmlstr="<table class='inputtable'>"
htmlstr+='<tr><td>firstname:<td colspan=5>'+firstname
htmlstr+='<tr><td>lastname:<td colspan=5>'+lastname

Then iterate through all the items in the document and extract the relevant information to create the HTML string that is used to publish this information to the user.


Listing 14. Extract HTML that allows publishing
                itemInfo.find("//item",null,true);
htmlstr+='<tr><td>itemID<td>description<td>date<td>price<td>insurance';
for(var j=0;itemInfo.currentFind.length>j ;j++)
 {
 var id= itemInfo.getValue("@ID",j);
var description= itemInfo.getValue("@description",j);
var purchaseDate= itemInfo.getValue("@purchaseDate",j);
var price= itemInfo.getValue("@price",j);
var insurance= itemInfo.getValue("insurance/text()",j);
var currency= itemInfo.getValue("insurance/@currency",j);
htmlstr+='<tr><td>'+id+'<td>'+description+'<td>' +purchaseDate+
'<td>' +currency+price++'<td>' +insurance;
}
document.getElementById("profilediv").innerHTML=htmlstr;
}

Note the similarity between the JavaScript code in the client that used XPath to search and iterate over the item elements to that of the Java code in the application server defined before.


Object data model

Even if you had used a standard Object data model approach, your application layer data objects would still need to be serialized to a format that is understandable by the client. Since the objects are complex, you would have basically two options:

1. Generate the client page in the application layer and fill in the data in the appropriate section of the web page (ASP/JSP approach). Then expose multiple APIs to accept any user modifications to the data. The problems with this approach are:

  • It mixes client and application server code which creates a sloppy architecture;
  • It requires more APIs to be created and documented in order for the client to pass back any major modifications to the data.

2. Generate a data structure that can be sent to the client as a string. The most acceptable format for representing such a serialized data structure is XML. The problem with this approach is that:

  • You have to now write extra code to do the serialization.
  • If the updated data from the client is XML, then more code is needed in the application server to interpret the modified XML back to application data objects.

An obvious question that arises is: If you have to resort to the XML Data Model for communicating with the client, then why not use it in the application layer itself?

You still need to manipulate the information that you got as a result to the insurance rate web service. Since this information is in XML, you need to first decompose it to your object model. If your data was stored in the database as XML, you could pass the XML to the customerItemsWithInsurance stored procedure. The problem with this approach is that if you are storing the data as XML and you are using the Object Model in the application, all kinds of mapping and transform issues arise.

If the data was stored in the database in a relational schema, your queries to the database would become more complex. Plus, you would have to write additional code in the middle tier to map the relational data to an Object Data Model or an XML Data Model.


Conclusion

In a Web Oriented Architecture, data needs to be serialized across different layers of the application. The most acceptable way of transferring complex data between a web client and application server is XML. In each layer, the data can be queried, transformed, and updated, so if the XML nature of the data is maintained, then it is possible to use XML based technologies like XPath, DOM and XQuery to manipulate the data. This is the XML Data Model of programming and in the challenging world of business data integration it might well be the panacea.



Download

DescriptionNameSizeDownload method
DOM and XPath wrapper class for javascriptsxmlparse.zip9 KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

  • DB2 Viper 2 Open Beta

  • Download a free trial version of DB2 Enterprise 9.

  • Now you can use DB2 for free. Download DB2 Express-C, a no-charge version of DB2 Express Edition for the community that offers the same core data features as DB2 Express Edtion and provides a solid base to build and deploy applications.

About the author

Hardeep Singh is a member of the advanced technologies group. He is the architect for DB2 XML tooling and XML migration. He has over 23 years of industry experience.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Information Management, XML, SOA and Web services, Web development
ArticleID=248831
ArticleTitle=Program with XML for DB2, Part 3: Program with XML in the client
publish-date=08162007
author1-email=hardeep@us.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers