 | 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.
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
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
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 | Description | Name | Size | Download method |
|---|
| Java XForms samples | xforms_java_.source.zip | 5KB | HTTP |
|---|
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
|  |