Skip to main content

XForms tip: Accepting XForms data in Java

Nicholas Chase (ibmquestions@nicholaschase.com), Freelance writer, Backstop Media
Nicholas Chase has been involved in Web site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. Nick has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, an Oracle instructor, and the Chief Technology Officer of an interactive communications company. He is the author of several books, including XML Primer Plus (Sam's).

Summary:  Much has been made about the ability of XForms to provide interactivity, and to submit information in XML. But none of that will do you any good unless you have a way to analyze the data once you send it to the server. This tip shows you how to access the submitted XML data using a Java™ servlet.

View more content in this series

Date:  03 Oct 2006
Level:  Intermediate
Activity:  4187 views

Browsers tested on

The XForms samples described in this tip have been tested and work with Firefox 1.5 (with the XForms extension installed) and Microsoft Internet Explorer 6 with the Formsplayer control installed. The download contains the XHTML file for Firefox and the HTML file for IE.

The instance data

Consider the example of an application meant to manage items bought at auction. It would look something like what is shown in Listing 1.


Listing 1. The instance data

<auctionRecords  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
   <auctionItem itemID="1"> 
      <purchaseDate>9/18/06</purchaseDate>
      <auctionLength xsi:type="xsd:int">86</auctionLength>
      <purchasePrice>20</purchasePrice>
      <description>McCoy train decanter (red)</description> 
      <estimatedValue>35</estimatedValue>
   </auctionItem>
   <auctionItem itemID="2">
      <purchaseDate>9/18/06</purchaseDate>
      <auctionLength xsi:type="xsd:int">32</auctionLength>
      <purchasePrice>10</purchasePrice>
      <description>Vintage hair dryer</description>
      <estimatedValue>N/A</estimatedValue>
   </auctionItem>
</auctionRecords>

The form has the ability to edit or delete existing items and add new ones.


The form

When you create the form, you have several options for submission. This tip deals with simple POST requests (see Listing 2).


Listing 2. The form

<?xml version="1.0" encoding="ASCII"?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ev="http://www.w3.org/2001/xml-events"  
    xmlns:xforms="http://www.w3.org/2002/xforms">
  <head>
    <title>Instance Data-To-XHTML/XForms Example</title>
    <xforms:model id="model_auctionRecords">

      <xforms:instance id="instance_model_auctionRecords" 
                                           src="auctions.xml"/>
      <xforms:submission id="submit_model_auctionRecords" method="post"
           action="http://localhost:8080/MakeItWork/AcceptData" />

    </xforms:model>
    <link href="gen_default.css" rel="stylesheet"/>
  </head>
  <body>
  
    <h1 align="center">Auction Item Inventory</h1>
  
    <xforms:repeat model="model_auctionRecords" 
        id="repeat_auctionItem_model_auctionRecords"
        nodeset="/auctionRecords/auctionItem">
      <xforms:input ref="." model="model_auctionRecords">
        <xforms:label>Auction Item</xforms:label>
      </xforms:input>
      <xforms:input ref="./@itemID" model="model_auctionRecords">
        <xforms:label>ItemID</xforms:label>
      </xforms:input>
      <xforms:input ref="purchaseDate" model="model_auctionRecords">
        <xforms:label>Purchase Date</xforms:label>
      </xforms:input>
      <xforms:input ref="auctionLength" model="model_auctionRecords">
        <xforms:label>Auction Length</xforms:label>
        <xforms:message level="modal" ev:event="xforms-invalid">The 
                  Auction Length is the duration of the auction for 
                  This item, in seconds.  It must be an integer 
                  value.</xforms:message>
      </xforms:input>
      <xforms:input ref="purchasePrice" model="model_auctionRecords">
        <xforms:label>Purchase Price</xforms:label>
      </xforms:input>
      <xforms:input ref="description" model="model_auctionRecords">
        <xforms:label>Description</xforms:label>
      </xforms:input>
      <xforms:input ref="estimatedValue" model="model_auctionRecords">
        <xforms:label>Estimated Value</xforms:label>
      </xforms:input>
      <xforms:upload ref="image" model="model_auctionRecords">
        <xforms:label>Upload Photo</xforms:label>
        <xforms:filename ref="./@filename"  />
        <xforms:mediatype ref="./image/@mediaType" />
      </xforms:upload>
    </xforms:repeat>
    <xforms:group>
      <xforms:trigger>
        <xforms:label>Add Auction Item</xforms:label>
        <xforms:insert ev:event="DOMActivate" 
            at="index('repeat_auctionItem_model_auctionRecords')"
            position="after" nodeset="/auctionRecords/auctionItem"/>
      </xforms:trigger>
      <xforms:trigger>
        <xforms:label>Delete Auction Item</xforms:label>
        <xforms:delete ev:event="DOMActivate" 
            at="index('repeat_auctionItem_model_auctionRecords')"
            nodeset="/auctionRecords/auctionItem"/>
      </xforms:trigger>
    </xforms:group>
    <xforms:submit submission="submit_model_auctionRecords">
      <xforms:label>Submit</xforms:label>
    </xforms:submit>
  </body>
</html>

Notice that nothing strange has been done with the data shown in Listing 2. There are no strange encoding schemes, and the destination, or action, is a simple Java™ servlet. A form submitted in this way simply sends the XML instance document as the contents of a POST request.


The basic servlet

Because the data will be submitted as a POST request, you only need to implement the doGet() method (see Listing 3).


Listing 3. The basic servlet

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class AcceptData extends javax.servlet.http.HttpServlet 
                               implements javax.servlet.Servlet {
   
   protected void doPost(HttpServletRequest request, 
                         HttpServletResponse response) 
                     throws ServletException, IOException {

      int length = request.getContentLength();
      response.getWriter().print(length);
   }               
}

In addition to the import statements needed for the rest of the servlet, the servlet simply obtains the size of the request, which includes the content of the POST, and outputs it to the Web page. If you submit the form, you will see a number such as 748 output to the browser, as in Figure 1.


Figure 1. Executing the simple servlet
executing the simple

That shows that there is data to be retrieved, but surely there are more useful things you can do with it.


Retrieve the data as a String

The next step up is to retrieve the actual data as a String, which enables you to output it back to the browser as a check that you really are submitting what you think you are submitting (see Listing 4).


Listing 4. Retrieve the data as a string

...
public class AcceptData extends javax.servlet.http.HttpServlet 
                               implements javax.servlet.Servlet {

   private String getRequestAsString(HttpServletRequest request) 
                                          throws java.io.IOException {

      BufferedReader requestData = new BufferedReader(
                      new InputStreamReader(request.getInputStream()));
      StringBuffer stringBuffer = new StringBuffer();
      String line;
      try{
         while ((line = requestData.readLine()) != null) {
            stringBuffer.append(line);
         }
      } catch (Exception e){
      }
      return stringBuffer.toString();

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

      try {
         int length = request.getContentLength();
        
         String content = 
             String content = getRequestAsString(request);
         response.getWriter().println(content);
                   
      } catch (Exception e){
         e.printStackTrace();
      }
   }
}

As you can see, the servlet requests provide this as way to access the data as an InputStream, and you can use that object to convert the data into a simple String object. If you submit the form now, you should see the instance document echoed back at you, as shown in Figure 2.


Figure 2. The instance document
instance document

Access the XML as a DOM Document

But what if you want to actually work with the data? Fortunately, that is not a problem, since you already have the XML as a String (see Listing 5).


Listing 5. Working with the XML data

...
   protected void doPost(HttpServletRequest request, 
                         HttpServletResponse response) 
                     throws ServletException, IOException {
      try {
         int length = request.getContentLength();
      
         String content = 
                                    getRequestAsString(request);
      
      DocumentBuilder builder = 
        DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document saveDocument = 
           builder.parse(new InputSource(new StringReader(content)));
      
        response.getWriter().println("The root element is "
                   +saveDocument.getDocumentElement().getNodeName());
              
      } catch (Exception e){
         e.printStackTrace();
      }
   }
}

First, build a new DocumentBuilder, and use it to create a new Document by parsing the content String. From there, you can use it just as you would use any other DOM Document, such as outputting the name of the root element, as you're doing here.


Summary

Because the XML data is submitted as the body of a POST request, you can easily access it from a Java servlet by retrieving and parsing the string value of that request. From there, the data is no different than it would be had it been obtained by more traditional means.



Download

DescriptionNameSizeDownload method
Java XForms samplesxforms_java_.source.zip5KB HTTP

Information about download methods


Resources

About the author

Nicholas Chase has been involved in Web site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. Nick has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, an Oracle instructor, and the Chief Technology Officer of an interactive communications company. He is the author of several books, including XML Primer Plus (Sam's).

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=XML, Java technology
ArticleID=164714
ArticleTitle=XForms tip: Accepting XForms data in Java
publish-date=10032006
author1-email=ibmquestions@nicholaschase.com
author1-email-cc=dwxed@us.ibm.com

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).

Rate a product. Write a review.

Special offers