///Servlets and XML: Made for Each Other

Servlets and XML: Made for Each Other

Our first sample servlet

To get things started, we’ll write a 10-line servlet that generates an XML document. As we build our XML-aware servlets, we’ll follow three steps:

  1. Set the content type to text/xml.
  2. Create the XML document.
  3. Write the XML document back to the client.

In most of our servlets, most of our effort will be in the second step. We might create an XML document from a database query, we might generate it based on an HTTP parameter passed to us from the client, or we might use some other kind of data retrieval or generation method. In our examples here, we’ll focus on HTTP parameters and database queries.

A very basic servlet

For our first example, the middle step of creating the XML document is not our concern; we simply want to generate a valid XML document. We’ve hardcoded the document into our source code, shown in Listing 1.

Listing 1. xmlfromscratch.java



publicclassxmlfromscratchextendsHttpServlet
{
publicvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)
throwsIOException, ServletException
{
response.setContentType("text/xml");
PrintWriterout = response.getWriter();

out.println("");
out.println("");
out.println(" Hello, World!");
out.println("
");
}
}

The result generated by this exciting piece of code looks like this:

Listing 2. Results from xmlfromscratch.java




Hello, World!


You can see an HTML view of the complete listing or view the Java source file directly.

Generating XML fragments

Well, we’ve created a servlet that is hardcoded to generate a simple, useless XML document. In this next servlet, we build a DOM tree from scratch, then we print some of the DOM tree back to the requestor. The part of the DOM tree that gets sent back to the requestor depends on the HTTP parameters our servlet receives. This example illustrates a couple of useful techniques: using HTTP parameters to control processing and generating a DOM tree without an XML source document.

Listing 3 shows the section of the code that processes the HTTP parameters:

Listing 3. xmlfromdom.java



publicvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)
throwsIOException, ServletException
{
response.setContentType("text/xml");
PrintWriterout = response.getWriter();

Enumerationkeys;
Stringkey;
StringrequestedSubtree = "";

keys = request.getParameterNames();
while (keys.hasMoreElements())
{
key = (String) keys.nextElement();
if (key.equalsIgnoreCase("subtree"))
requestedSubtree = request.getParameter(key);
}

As in our earlier example, we set the content type to text/xml. Once that’s done, we use the HttpServletRequest.getParameterNames method to retrieve all the parameters from the HTTP request.

After we’ve processed the parameters, we need to find the information the user requested. The information we’re using builds a DOM tree from objects; that DOM tree contains the text of a Shakespearean sonnet, along with other information about the sonnet. We’ll return a portion of the DOM tree based on the HTTP subtree parameter. Listing 4 shows some of the code that builds the DOM tree:

Listing 4. Build the DOM tree



Documentdoc = null;
Elementauthor = null;
Elementlines = null;
Elementtitle = null;

publicvoidinitialize()
{
doc = (Document)Class.
forName("org.apache.xerces.dom.DocumentImpl").
newInstance();

if (doc != null)
{
Elementroot = doc.createElement("sonnet");
root.setAttribute("type", "Shakespearean");

author = doc.createElement("author");

ElementlastName = doc.createElement("last-name");
lastName.appendChild(doc.createTextNode("Shakespeare"));
author.appendChild(lastName);

We create an instance of the Java class that implements the DOM Document interface, then we ask that node to create various nodes for us. You could easily rewrite this application to generate the DOM tree by parsing an XML file. To simplify the example (and to lighten my workload) we’ve defined instance variables that hold the values of the nodes we intend to serve. These values are declared at the top of the class declaration, and are initialized in the initialize method.

Our last step is to deliver the requested part of the DOM tree back to the user. To do this, we use a recursive method, printDOMTree, that processes a node and all of its children. Because the method is recursive, it doesn’t matter if we start at the root node of the document or anywhere else in the DOM tree. If the request is for one of the nodes we know about, we pass that node to the printDOMTree method. Otherwise, we pass the Document node. Listing 5 shows this step.

Listing 5. printDOMTree



if (requestedSubtree.equalsIgnoreCase("author"))
printDOMTree(author, out);
elseif (requestedSubtree.equalsIgnoreCase("lines"))
printDOMTree(lines, out);
elseif (requestedSubtree.equalsIgnoreCase("title"))
printDOMTree(title, out);
else
printDOMTree(doc, out);

If the subtree parameter is author, the results are:




Shakespeare
William
British
1564
1616

If the subtree parameter is title, the results are:

 

You can see the HTML view of the complete listing or view the Java source file directly.

Interfacing with a database

Our final example generates XML from a database query. There are many ways of doing this; for this example, we’ll use IBM XML Extender for DB2 (see Resources). This free product lets you store XML documents in DB2. Our query extracts those documents from DB2, then passes them on to the user.

If you’re using Oracle 8i instead of DB2, you’ll find that it boasts similar functions (see Resources). For databases that aren’t XML-aware, you could store the XML document as a character large object (CLOB) and retrieve the document as a chunk of text.

However your database is set up, you need to do three things to get this code to work:

  1. First, change the DbOwner, DbUserid, and DbPasswd variables to the correct values for your system.
    
    
    ///////////////////////////////////////////////////////////////////////////////

    // Be sure to change these three strings appropriately, or the //

    // servlet won't work. //

    ///////////////////////////////////////////////////////////////////////////////

    DbUserid = "xxxxxxxx";

    DbPasswd = "xxxxxxxx";

    DbOwner = "xxxxxxxx";
  2. Next, use the JDBC driver that works with your system. We’re using DB2.

    
    
    staticStringJDBCDriver = "COM.ibm.db2.jdbc.app.DB2Driver";

    ...

    try

    {

    Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance();

    }

    catch (Exceptione)

    {

    System.out.println("Can't get the driver!"); e.printStackTrace();

    }
  3. If you want to, change the SQL query. To keep the demo simple, we’re simply retrieving all of the XML documents from the order column in the sales_order_view table.

    
    
    // We hardcoded the SQL statement here; this would be more

    // sophisticated if we qualified the query based on user input.

    Stringquery = "select order from " + DbOwner + ".sales_order_view";

In the service method, our servlet connects to DB2, executes a query (the results of which are a set of XML documents), parses the query results, and writes the parsed data to the output stream. Listing 6 shows the most relevant sections of the code:

Listing 6. xmlfromdb2.java



// We hardcoded the SQL statement here; this would be more
// sophisticated if we qualified the query based on user input.
Stringquery = "select order from " + DbOwner + ".sales_order_view";

res.setContentType("text/xml");

try
{
ConInfoindex = newConInfo();
Connectioncon = getCon(index);
Statementstmt = con.createStatement();
ResultSetrs = stmt.executeQuery(query);

...

// Display the result set. We take the XML doc from each row,
// parse it, then print the DOM tree. rs.next() returns
// false when there are no more rows.
while (rs.next())
{
StringnextOrder = rs.getString(1).trim();
Documentdoc = null;
StringReadersr = newStringReader(nextOrder);
InputSourceiSrc = newInputSource(sr);

try
{
parser.parse(iSrc);
doc = parser.getDocument();
}
catch (Exceptione)
{
System.err.println("Sorry, an error occurred: " + e);
}

if (doc != null)
printDOMTree(doc, out);
}

To see all the details, check out the HTML view of the complete listing or view the Java source file directly.

Summary

Although none of the example servlets will change the world, they do illustrate how well XML and servlets work together. Servlets perform as a great mechanism for delivering content to clients, and XML makes a wonderful mechanism for delivering structured data. You can also use servlets to process XML documents on the server and deliver their contents to clients. Best of all, both of these technologies are cross-platform, giving you more flexibility and portability in your applications.

Resources

  • Find out more about DB2 XML Extender. The documentation that comes with the product has an in-depth tutorial that helps you bring XML documents into the world of relational databases.
  • Try out the free servlet tutorial from WebSphere.
  • Delve deeper into how to parse an XML file in the developerWorks’ tutorial XML programming in Java.
  • Download a PDF version of the presentation the author made to the City Java user group.
  • Learn about color-coding your listings with Emacs at www.gnu.org.
  • 2010-05-26T11:18:30+00:00 May 18th, 2005|XML|0 Comments

    About the Author:

    Doug Tidwell is a Senior Programmer and Cyber Evangelist at IBM. He has more than a seventh of a century of programming experience and has been working with XML-like applications for several years. His work as a Cyber Evangelist is basically to look busy, and to help customers evaluate and implement XML technology. Using a specially designed pair of zircon-encrusted tweezers, he holds a Masters Degree in Computer Science from Vanderbilt University and a Bachelors Degree in English from the University of Georgia. He can be reached at dtidwell@us.ibm.com.

    Leave A Comment