Skip to main content

skip to main content

developerWorks  >  XML | Java technology  >

XForms tip: Accepting XForms data in Java

developerWorks
Document options

Document options requiring JavaScript are not displayed

Discuss

Sample code


Rate this page

Help us improve this content


Level: Intermediate

Nicholas Chase (ibmquestions@nicholaschase.com), Freelance writer, Backstop Media

03 Oct 2006

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



Back to top


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.



Back to top


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.



Back to top


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


Back to top


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.



Back to top


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.




Back to top


Download

DescriptionNameSizeDownload method
Java XForms samplesxforms_java_.source.zip5KBHTTP
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).




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top