Tuesday 12 August 2008

Generating Java Map List and Displaying with JSP

This example is to demonstrate recent investigations into outputting xml data to the page using a Java HTTPServlet and JSP with a Map List.

We want to output the id, description and size for each widget from the xml, to a form in html.
The id is stored in its own element but the description and size are name value pair properties.

<?xml version="1.0" encoding="UTF-8"?>
<widgetNode>
<widget>
<id>101</id>
<properties>
<property>
<name>description</name>
<value>Thingy Bolt</value>
</property>
<property>
<name>size</name>
<value>27</value>
</property>
</widget>
<widget>
<id>102</id>
<properties>
<property>
<name>description</name>
<value>Wotsit Nut</value>
</property>
<property>
<name>size</name>
<value>11</value>
</property>
</widget>
</widgetNode>


The Java extract here loops through each widget node, adding the values we want to Map, then adds that Map to a List.
The Map List is then added, as an attribute, to the request.

(Although unintended, this is also an example for XPath, which took a little investigation too)

...
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
...

private void processWidgetXml(HttpServletRequest request, String xml) {
List<Map<String,String>> widgets = new ArrayList<Map<String,String>>();
String expression = "/widgets/widget";
try {
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList)xPath.evaluate(expression, new InputSource(new StringReader(xml)),XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
Map<String,String> widgetMap = new HashMap<String,String>();
widgetMap.put("id", (String)xPath.evaluate("id", node));
widgetMap.put("description", (String)xPath.evaluate("properties/property[name='description']/value", node));
widgetMap.put("size", (String)xPath.evaluate("properties/property[name='size']/value", node));
widgets.add(widgetMap);
}
request.setAttribute("widgets", widgets);
} catch (XPathExpressionException e) {
System.err.println("XPath expression invalid: "+e.getMessage());
e.printStackTrace();
}
}

Coming to the JSP, the following extract highlights the syntax for the Map List. It loops through all of the widgets, creating a form, with unique name, for each widget.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
...
<% int lc = 0; %>
<c:forEach var="widget" items="${widgets}">
<form name="myWidget<%= lc %>" action="/myActionPage" method="post">
<input type="hidden" name="widgetId" value="${widget['id']}"/>
<input type="submit" value="Select"/>
${widget['description']} : ${widget['size']}
</form>
<% lc++; %>
</c:forEach>


Done... (finally)

No comments: