Exercise 2: Create Web Application Project
(30 minutes)
The goal of this exercise
is to let you build a simple Netbeans Web Application Project by
following step by step instructions.
Steps to Follow
- If NetBeans is not already running, start it.
- Select File Menu
- Select New Project
- Select Category 'Java Web' and Project 'Web Application'
- Press 'Next'

Figure-01: New Project: Choose Project
- In the next dialog, do the following
- Set 'Project Name' to CustomerInvoice
- Set 'Project Location' to '<lab_root>' - note for JavaOne attendees:
this is correct as it is - just keep the default.
- Press 'Next'

Figure-02: New Web Application: Name and Location
-
In the next dialog, do the following
- Set 'Server' to 'Glassfish V2'
- Set 'Java EE Version' to 'Java EE 5'
- Press 'Finish'

Figure-03: New Web Application: Server and Settings
-
After the project creation, the index.jsp file is automatically opened by NetBeans. This is how it looks like:

Figure-04: New Web Application: Project View
- The following code creates a web application form to get data. Replace the complete content of the index.jsp file with it:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Invoice</title>
</head>
<body>
<h2>Create a Customer Invoice</h2>
<form action="createInvoice.jsp" method="POST">
<table border="0">
<tbody>
<tr>
<td>Name, First Name</td>
<td><input type="text" name="myName" value=""/></td>
</tr>
<tr>
<td>Street</td>
<td><input type="text" name="myStreet" value=""/></td>
</tr>
<tr>
<td>Zip Code</td>
<td><input type="text" name="myZip" value=""/></td>
</tr>
<tr>
<td>City</td>
<td><input type="text" name="myCity" value=""/></td>
</tr>
</tbody>
</table>
<table border="0">
<thead>
<tr>
<th>Product ID</th>
<th>Product Name</th>
<th>Quantity</th>
<th>Single Price</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" name="myProdID" value=""/></td>
<td><input type="text" name="myProdName" value=""/></td>
<td><input type="text" name="myProdQuantity" value=""/></td>
<td><input type="text" name="myProdPrice" value=""/></td>
</tr>
<tr>
<td><input type="text" name="myProdID" value=""/></td>
<td><input type="text" name="myProdName" value=""/></td>
<td><input type="text" name="myProdQuantity" value=""/></td>
<td><input type="text" name="myProdPrice" value=""/></td>
</tr>
<tr>
<td><input type="text" name="myProdID" value=""/></td>
<td><input type="text" name="myProdName" value=""/></td>
<td><input type="text" name="myProdQuantity" value=""/></td>
<td><input type="text" name="myProdPrice" value=""/></td>
</tr>
</tbody>
</table>
<input type="submit" value="Send" />
</form>
</body>
</html>
Do not forget to save the file.
-
We are adding some jar libraries to our project - for future usage.
Right-click the CustomerInvoice project and choose 'Properties'.
In the 'Libraries' category, click 'Add JAR/Folder'. Add the following libraries
to the project:
- <lab_root>/resources/odfdom/jars/xercesImpl.jar
- <lab_root>/resources/odfdom/jars/odfdom.jar
For JavaOne attendees, the libraries are here:
- /export/home/lab5569/odfdom/resources/odfdom/jars/xercesImpl.jar
- /export/home/lab5569/odfdom/resources/odfdom/jars/odfdom.jar
Click "OK" afterwards.
Figure-05: Add required libraries to the project
Press F6 to start the project. Verify the
form in your browser. Note that it may take a while to start glassfish.
Figure-06: Verify the form in the browser
-
In Netbeans, right-click the 'Web Pages' folder and create
a new JSP file named "createInvoice". Use the default settings
in the 'New JSP File' dialog.
Figure-07: createInvoice JSP File
-
You have to add a couple of 'imports' to the "createInvoice.jsp"
file:
<%@page import="java.text.*,
java.util.*,
org.w3c.dom.*,
org.odftoolkit.odfdom.dom.OdfNamespace,
org.odftoolkit.odfdom.dom.type.OdfPositiveInteger,
org.odftoolkit.odfdom.doc.OdfDocument,
org.odftoolkit.odfdom.doc.OdfFileDom,
org.odftoolkit.odfdom.doc.element.text.*,
org.odftoolkit.odfdom.doc.element.office.*,
org.odftoolkit.odfdom.doc.element.table.*,
javax.xml.xpath.*" %>
Figure-08: Add required imports
-
Now change the text of the h1 element in "createInvoice.jsp" to 'Customer invoice generated.'
-
Store the data which has been passed from the web front end
form in variables. The data can be accessed using the
getParameter() method of the request object. The parameter
of the getParameter method is the name of the text input
form which has been assigned in index.jsp. You will need to
define the following variables:
<%
String name = request.getParameter("myName");
String street = request.getParameter("myStreet");
String zip = request.getParameter("myZip");
String city = request.getParameter("myCity");
String[] productIds = request.getParameterValues("myProdID");
String[] productNames = request.getParameterValues("myProdName");
String[] productQuantities = request.getParameterValues("myProdQuantity");
String[] productPrices = request.getParameterValues("myProdPrice");
%>
This code has to be inserted after the h1 element and has to
be enclosed by '<%' and '%>' to denote that this is Java code.
Figure-09: Get data from request
-
We will extend the Java part in the "createInvoice.jsp" file.
Now we start using the ODFDOM API. First we want to open
a template bill file and get access to the content dom.
OdfDocument document = OdfDocument.loadDocument("/export/home/lab5569/odfdom/resources/invoice_template.odt");
OdfFileDom content = document.getContentDom();
Please note that you have to adjust the file location
passed to the loadDocument method.
-
Have a look at the template bill document. This document
contains 4 placeholder fields: _NAME_, _STREET_,
_ZIPCITY_, and _CURRENTDATE_. We want to replace the
address placeholder fields with the data from the web
front end and the date placeholder field should be
replaced with the current date.
For this we first create 4 new OdfSpan objects:
OdfSpan spanName = new OdfSpan(content);
spanName.setTextContent(name);
OdfSpan spanStreet = new OdfSpan(content);
spanStreet.setTextContent(street);
OdfSpan spanCity = new OdfSpan(content);
spanCity.setTextContent(zip + " " + city);
OdfSpan spanDate = new OdfSpan(content);
SimpleDateFormat dateFormater = new SimpleDateFormat();
String dateStr = dateFormater.getDateInstance(DateFormat.FULL).format(new Date());
spanDate.setTextContent(dateStr);
-
In order to find the placeholder fields in the template
document, we use a xpath. The result is returned in a
NodeList. Please note that the namespace context has to
be set to the OdfNamespace. Alternatively, we could use
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new OdfNamespace());
NodeList placeholder = (NodeList)xpath.evaluate("//text:placeholder", content, XPathConstants.NODESET);
-
Now we can iterate over the found placeholder fields and
replace them with our new spans:
for(int i=0; i<placeholder.getLength(); i++) {
OdfPlaceholder pl = (OdfPlaceholder)placeholder.item(i);
OdfParagraph parentParagraph = (OdfParagraph)pl.getParentNode();
String placeholderText = pl.getTextContent();
if(placeholderText.indexOf("_NAME_") > 0) {
parentParagraph.replaceChild(spanName, pl);
} else if(placeholderText.indexOf("_STREET_") > 0) {
parentParagraph.replaceChild(spanStreet, pl);
} else if(placeholderText.indexOf("_ZIPCITY_") > 0) {
parentParagraph.replaceChild(spanCity, pl);
} else if(placeholderText.indexOf("_CURRENTDATE_") > 0) {
parentParagraph.replaceChild(spanDate, pl);
}
}
-
We also want to fill the table in the template bill with
the data from the web front end. So we first need to get
access to the table in the template bill content dom:
xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new OdfNamespace());
OdfTable table = (OdfTable)xpath.evaluate("//table:table[1]", content, XPathConstants.NODE);
Since there's only one table in the template document,
we can access this directly without using a NodeList.
-
We append a new table row for each set of data obtained
from the web frontend. Each of these rows will consist of
5 table cells containing a paragraph with the following data:
- the product ID
- the product name
- the product quantity
- the product single price and
- the total price
The style for the table cells should be a copied from the
respective cells in the first table row. The style for the
paragraphs in the table cells should be "Table_20_Contents".
This style is a document style of the bill template
document. The last row of the table should state the
overall price in the last table cell.
OdfTableRow firstRow = (OdfTableRow)table.getElementsByTagName("table:table-row").item(0);
float priceOverall = 0;
for(int i=0; i < productIds.length; i++) {
OdfTableRow billingItemRow = new OdfTableRow(content);
for(int j=0; j < 5; j++) {
OdfTableCell cell = new OdfTableCell(content);
cell.setStyleName( ((OdfTableCell)firstRow.getCellAt(j)).getStyleName() );
OdfParagraph paragraph = new OdfParagraph(content);
paragraph.setStyleName( "Table_20_Contents" );
if(j == 0) {
paragraph.setTextContent(productIds[i]);
} else if(j == 1) {
paragraph.setTextContent(productNames[i]);
} else if(j == 2) {
paragraph.setTextContent(productQuantities[i]);
} else if(j == 3) {
paragraph.setTextContent(productPrices[i]);
} else if(j == 4) {
float priceTotal = Float.parseFloat(productPrices[i])*Float.parseFloat(productQuantities[i]);
priceOverall += priceTotal;
paragraph.setTextContent(String.valueOf(priceTotal));
}
cell.appendChild(paragraph);
billingItemRow.appendCell(cell);
}
table.appendRow(billingItemRow);
}
-
The last row of the table should state the overall price
for the customer bill. It shall consist of two cells, the
first of which has a column span of 4 and the second
contains a new paragraph with the overall price. The
paragraph style for this is "SumPrice".
OdfTableRow lastRow = new OdfTableRow(content);
OdfTableCell cell = new OdfTableCell(content);
cell.setNumberColumnsSpanned(OdfPositiveInteger.valueOf("4"));
lastRow.appendCell(cell);
cell = new OdfTableCell(content);
OdfParagraph paragraphFullPrice = new OdfParagraph(content);
paragraphFullPrice.setStyleName("SumPrice");
paragraphFullPrice.setTextContent(String.valueOf(priceOverall));
cell.appendChild(paragraphFullPrice);
lastRow.appendCell(cell);
table.appendRow(lastRow);
-
Finally, we save the file:
document.save("/export/home/lab5569/NetBeansProjects/CustomerInvoice/invoice_final.odt");
-
The whole "ceateInvoice.jsp" file can be viewed here:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="java.text.*,
java.util.*,
org.w3c.dom.*,
org.odftoolkit.odfdom.dom.OdfNamespace,
org.odftoolkit.odfdom.dom.type.OdfPositiveInteger,
org.odftoolkit.odfdom.doc.OdfDocument,
org.odftoolkit.odfdom.doc.OdfFileDom,
org.odftoolkit.odfdom.doc.element.text.*,
org.odftoolkit.odfdom.doc.element.office.*,
org.odftoolkit.odfdom.doc.element.table.*,
javax.xml.xpath.*"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Customer invoice generated.</h1>
String name = request.getParameter("myName");
String street = request.getParameter("myStreet");
String zip = request.getParameter("myZip");
String city = request.getParameter("myCity");
String[] productIds = request.getParameterValues("myProdID");
String[] productNames = request.getParameterValues("myProdName");
String[] productQuantities = request.getParameterValues("myProdQuantity");
String[] productPrices = request.getParameterValues("myProdPrice");
OdfDocument document = OdfDocument.loadDocument("/export/home/lab5569/odfdom/resources/invoice_template.odt");
OdfFileDom content = document.getContentDom();
OdfSpan spanName = new OdfSpan(content);
spanName.setTextContent(name);
OdfSpan spanStreet = new OdfSpan(content);
spanStreet.setTextContent(street);
OdfSpan spanCity = new OdfSpan(content);
spanCity.setTextContent(zip + " " + city);
OdfSpan spanDate = new OdfSpan(content);
SimpleDateFormat dateFormater = new SimpleDateFormat();
String dateStr = dateFormater.getDateInstance(DateFormat.FULL).format(new Date());
spanDate.setTextContent(dateStr);
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new OdfNamespace());
NodeList placeholder = (NodeList)xpath.evaluate("//text:placeholder", content, XPathConstants.NODESET);
for(int i=0; i<placeholder.getLength(); i++) {
OdfPlaceholder pl = (OdfPlaceholder)placeholder.item(i);
OdfParagraph parentParagraph = (OdfParagraph)pl.getParentNode();
String placeholderText = pl.getTextContent();
if(placeholderText.indexOf("_NAME_") > 0) {
parentParagraph.replaceChild(spanName, pl);
} else if(placeholderText.indexOf("_STREET_") > 0) {
parentParagraph.replaceChild(spanStreet, pl);
} else if(placeholderText.indexOf("_ZIPCITY_") > 0) {
parentParagraph.replaceChild(spanCity, pl);
} else if(placeholderText.indexOf("_CURRENTDATE_") > 0) {
parentParagraph.replaceChild(spanDate, pl);
}
}
xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new OdfNamespace());
OdfTable table = (OdfTable)xpath.evaluate("//table:table[1]", content, XPathConstants.NODE);
OdfTableRow firstRow = (OdfTableRow)table.getElementsByTagName("table:table-row").item(0);
float priceOverall = 0;
for(int i=0; i < productIds.length; i++) {
OdfTableRow billingItemRow = new OdfTableRow(content);
for(int j=0; j < 5; j++) {
OdfTableCell cell = new OdfTableCell(content);
cell.setStyleName( ((OdfTableCell)firstRow.getCellAt(j)).getStyleName() );
OdfParagraph paragraph = new OdfParagraph(content);
paragraph.setStyleName( "Table_20_Contents" );
if(j == 0) {
paragraph.setTextContent(productIds[i]);
} else if(j == 1) {
paragraph.setTextContent(productNames[i]);
} else if(j == 2) {
paragraph.setTextContent(productQuantities[i]);
} else if(j == 3) {
paragraph.setTextContent(productPrices[i]);
} else if(j == 4) {
float priceTotal = Float.parseFloat(productPrices[i])*Float.parseFloat(productQuantities[i]);
priceOverall += priceTotal;
paragraph.setTextContent(String.valueOf(priceTotal));
}
cell.appendChild(paragraph);
billingItemRow.appendCell(cell);
}
table.appendRow(billingItemRow);
}
OdfTableRow lastRow = new OdfTableRow(content);
OdfTableCell cell = new OdfTableCell(content);
cell.setNumberColumnsSpanned(OdfPositiveInteger.valueOf("4"));
lastRow.appendCell(cell);
cell = new OdfTableCell(content);
OdfParagraph paragraphFullPrice = new OdfParagraph(content);
paragraphFullPrice.setStyleName("SumPrice");
paragraphFullPrice.setTextContent(String.valueOf(priceOverall));
cell.appendChild(paragraphFullPrice);
lastRow.appendCell(cell);
table.appendRow(lastRow);
document.save("/export/home/lab5569/NetBeansProjects/CustomerInvoice/invoice_final.odt");
</body>
</html>
-
You can now run the web application by pressing F6. If the
application does not what you expect it to do, you can
debug the code by pressing STRG+F5
When you fill out the web form and click on send, the
invoice_final.odt file is generated. Verify this by starting OpenOffice.org and load the invoice.
It could look like this:
Figure-10: The created customer invoice
Challenge
The example above produces an exception when not all fields in the table are filled. Fix this.
Hint: Debug the project to verify where the exception actually happens.
Summary
In this exercise, you learned how to create a new Netbeans Web
Application Project that gathers some data that is written into a
document using the ODF Toolkit.
Back to top
Next exercise
|