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.
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.
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.
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.
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.
| Description | Name | Size | Download method |
|---|---|---|---|
| Java XForms samples | xforms_java_.source.zip | 5KB | HTTP |
Information about download methods
- Participate in the discussion forum.
-
This series is a good guide for getting started using XForms.
-
Start here to learn about the Visual XForms Designer from alphaWorks.
-
Be sure to stop by the Java zone for all your Java resources.
-
In the
XML area on developerWorks, get the resources
you need to advance your skills in XForms and other XML technologies.
-
Browse the
technology bookstore for books on these and other technical topics.
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).




