Java Tip 140: Automatically generate JavaBeans from XSL files in J2EE applications
Use an XSL parameter parser to convert HTML parameter names to JavaBeans
In the Java 2 Platform, Enterprise Edition (J2EE) world, servlets complement applets on the server side and complete the definition of Java’s role in the client/server hierarchy and in multitiered applications. Nowadays, J2EE plays a prominent role in Java’s acceptance, and numerous “Java-completing” techniques exist like, XML, XSLT (Extensible Stylesheet Language Transformations), and Java object-to-XML conversion. Many available resources can help you learn about servlets, XML/XSLT, and HTML (see Resources). Therefore, I do not discuss those techniques here, but focus on a problem that plays an important role in the everyday life of a Web application developer who uses such techniques: writing Java statements that extract parameter values delivered by HTML form elements and produce corresponding JavaBeans as intermediate data storage. These beans manage the data flow between an application client (browser) and components running on the J2EE server, or between server components and a database. They hold either the data the user entered in HTML forms or, more generally, any attribute passed either on the URL or in a POST. For instance, a bean for a login page could have two properties: login and password. During request handling, such a bean converts to an XML tree.
Figure 1 shows the overall architecture of a J2EE application based on Sun Microsystems’ J2EE pattern recommendations and blueprints (see Resources). StrutsCX, an open source framework for building enterprise applications, also uses a similar architecture.
As a first step, the user typically fills out an input form and sends the data with a HTTP GET or POST request to the server. The Front Controller servlet (Front Controller is a Sun J2EE pattern) examines the request and instantiates one or more helper classes. A helper class’s important tasks include reading the request parameters the user sends, validating them if necessary, and storing them in a JavaBean. So, every page presented to the user corresponds to a JavaBean that serves as the model for the HTML view in the well-known Model-View-Controller (MVC) pattern.
After the bean has been filled with the user form data, it is translated into XML (e.g., using Castor, an open source project that transforms Java objects to XML). This XML stream is the input for an XSL transformation to produce the HTML output. XSLT is an official World Wide Web Consortium (W3C) standard for a flexible and powerful language that transforms the structure of XML data into text, PDF, HTML/XHTML (Extensible HTML), Wireless Markup Language (WML), VoiceXML, or any other XML format. An XSLT processor like Xalan or Saxon actually performs the transformation using an XSL stylesheet, which itself is an XML document (see Figure 2). You define rules for the XML data transformation inside the XSL stylesheet. The XSLT processor uses these rules during transformation. In this article’s context, the transformation is from XML to HTML.
Look at the HTML form
Because we create dynamic HTML output pages using servlets, XML, and XSL, let’s look closer at the HTML form elements that deliver user input data. As mentioned earlier, these HTML statements are embedded in XSL files. Therefore, we investigate XSL files to know what HTML input parameters must be read by a servlet’s helper class to examine a user request. Every HTML form element has a name and a value that will be delivered if a user fills the form with data or makes a selection in a choice or radio box. These relevant form tags are:
<input type="text" name="text_parameter_name"...
<input type="checkbox" name="checkbox_parameter_name"...
<input type="radio name="radio_button_name"...
and sometimes we need hidden parameters too, e.g.,
<input type="hidden" name="ReportName" value="First_Report"/>
If we need to examine the user data entered with these form tags in Java, we use the servlet’s request object. Such a statement looks like this:
String inputText1 = request.getParameter("text_parameter_name");
// Then check for null value
A better approach is to use the O’Reilly ParameterParser
(see Resources):
import com.oreilly.servlet.ParameterParser;
ParameterParser parser = new ParameterParser(request);
String inputText1= parser.getStringParameter("text_parameter_name", "");
// Provides a default value ("") too
This parser is especially useful when dealing with checkboxes:
boolean someBooleanValue = parser.getBooleanParameter("checkbox_parameter_name", false);
It is critical to have the right HTML form parameter name as a string in the Java statement. You should copy and paste from the XSL file into Java source code or read the parameter name in the XSL file and type it into the Java source. There is no other way. This is cumbersome and error-prone. Moreover, because each HTML form parameter value is in a Java variable, we need to store these values in corresponding JavaBeans that represent the intermediate model for an HTML page until the data has been saved in a database or enterprise information system. This means first coding a JavaBean by hand or with little support from an IDE, and second, calling every bean setter method to store the value. Here’s where this tip can help you.
Two generators
I developed two generators that ease a J2EE developer’s life when dealing with Java and XSL: the first one is a JavaBean generator and the second one is a parameter parser and bean “filler” generator (it produces setter method calls for a JavaBean generated with the first code generator). These generators are based on regular expression statements. I use Jakarta regular expressions, so you are not bound to Java 2 Platform, Standard Edition (J2SE) 1.4. Both generators use an argument parser that allows you to specify certain arguments in the command line (e.g., the generated JavaBean is dedicated to a special Java package and can implement an interface or extend a superclass). The most interesting part of the source code is the regular expressions definition block:
// The RE Patterns
private static final RE titlePattern = new RE("<title.+(/>|</title>)",
RE.MATCH_CASEINDEPENDENT);
private static final RE inputLinePattern = new RE("(<!--.*)|((<input.+(/>|</input>))|
(<select[^>]+>)|(<textarea[^>]+>l))", RE.MATCH_CASEINDEPENDENT);
private static final RE hiddenPattern = new RE("types*=s*"hidden"",
RE.MATCH_CASEINDEPENDENT);
private static final RE textPattern = new RE("types*=s*"text"",
RE.MATCH_CASEINDEPENDENT);
private static final RE cbPattern = new RE("types*=s*"checkbox"",
RE.MATCH_CASEINDEPENDENT);
private static final RE radioPattern = new RE("types*=s*"radio"",
RE.MATCH_CASEINDEPENDENT);
private static final RE namePattern = new RE("names*=s*"[^"]+"",
RE.MATCH_CASEINDEPENDENT);
As you can see, all relevant HTML form tags are part of these patterns. The XslBeanGenerator
(see Resources) scans XSL files for these tags and produces corresponding JavaBeans, where the parameter names are converted to bean member variables. The XslParameterParser
has two tasks: it first generates code to read the HTML form tag parameter values out of the servlet’s request object and then generates code to store these values in the corresponding JavaBean using its setter methods. Typically the generated code looks like this:
import com.oreilly.servlet.ParameterParser;
// Generated statement: use O'Reilly ParameterParser
ParameterParser parser = new ParameterParser(request);
// Generated statement
String username = parser.getStringParameter("username", "");
// Generated statement: read the HTML input text value
UserDataModel model = new UserDataModel();
// This statement or similar must be inserted by the user
// It instantiates the generated JavaBean
model.setUsername(username);
// Generated statement: calling bean setter method
For a complete example of an XSL file and the generated code by both parsers, download the source code from Resources below.
Keep parsing
This tip introduced two XSL file parsers that generate useful Java code when working with J2EE applications based on Java, XML, XSL, and XSLT. Both generators, XslBeanGenerator
and XslParameterParser
, fill the gap between XSL files and Java code that relies on information provided mainly by these XSL files’ HTML. One generator produces a JavaBean that holds the user data described in XSL/HTML. The other generator produces a Java code statement to read HTML request parameter values and stores these values in the corresponding bean.