| ★ wanayoo — archive 1999 http://developer.iplanet.com/viewsource/marchal_xml_p.htm | Nouvelle recherche | Portail wanayoo |
![]() |
![]() |
![]() |
downloads | ||||||||||||||||
| technologies | |||||||||||||||||||
| support |
![]() |
![]() |
|
Servlet Programming for Teams : By Benoît Marchal
How Java Programmers and HTML Designers Can Collaborate Using XML Send comments and questions about this article to View Source. [Editor's note: Since this article was published, the W3C has updated XSL. For further information, see More Servlet Programming for Teams: Style Sheet Changes and Advanced Techniques.] Servlets - Java's replacement for CGI scripts - are increasingly popular because they're more efficient than CGI scripts and are available on all major platforms. But there's one problem with servlets: they encourage you to mix the code for the presentation (HTML) with the code for the application logic (computing values, querying databases, and so on). This article presents a technique I developed for cleanly separating the presentation aspect from the application logic in Java servlets, to match the organization of most web site development teams into HTML designers and Java developers. The technique uses XML (Extensible Markup Language) and XSL (XML Stylesheet Language). You can download the source code for the example I'll use to illustrate the solution. ALL MIXED UPListing 1 shows a servlet that mixes presentation code and application logic. (The View Source article Adding Java Servlet API Capability to Netscape Servers: Introducing Live Software's JRun Servlet Engine describes how to use servlets with Netscape servers.) The servlet replies with an HTML file that's hard-coded in the servlet. Listing 1
protected void doGet(HttpServletRequest request,
HttpServletResponse resp)
throws IOException {
Writer w = response.getWriter();
w.write("<HTML>\n<HEAD>\n<TITLE>Pineapplesoft</TITLE>\n</HEAD>\n");
w.write("<BODY>\n");
w.write("<P>Pineapplesoft welcomes you to its servlet.\n");
w.write("<BR>You are visitor " + visitorCount++);
w.flush();
}
Sun has introduced Java Server Pages (JSP) as an alternative to servlets. (See the article Introduction to JavaServer Pages: Server-Side Scripting the Java Way.) JSP works the other way around: instead of embedding HTML in Java code, it embeds Java code in HTML. Although this makes servlet programming more accessible, it's hardly an improvement from a maintenance point of view. The major problem with mixing HTML and Java code is that it doesn't reflect how web site development teams are typically organized, into Java developers in charge of Java programming and HTML designers responsible for the presentation. Obviously the two sides need to work together, but they don't have the same priorities. Java developers are usually more concerned with the robustness and efficiency of their code than with the details of the presentation, while HTML designers need rapid turnover of presentation changes. My goals for a solution to this problem were:
XML TO THE RESCUEXML is a relatively new markup language that's been developed by the World Wide Web Consortium (W3C), the same organization that's in charge of HTML development. XML syntax is similar to HTML but, as its name implies, XML is extensible. In practice, this means that XML lets you create your own tags. HTML has a fixed set of tags ( <BODY>, <TITLE>, <P>, <IMG>, and so on) that were created by the W3C. XML has no built-in tags; it's up to you to create the tags you need. Whereas HTML has many tags that carry presentation instructions (including <FONT>, <CENTER>, and <PRE>), the tags you create in XML instead focus on the logical structure of the information. To render the information on the screen, you apply a style sheet - an approach that cleanly isolates the presentation.Listing 2 is an XML document for a shopping cart. The syntax will look familiar: as in HTML, tags are the names of elements enclosed in angle brackets, with a slash ( /) added in the end tag. However, you'll recognize none of the tags you're used to from HTML; the tags used here have been created specifically for this application.Listing 2
<?xml version="1.0" encoding="ISO-8859-1"?>
<shopping-cart>
<product id="0">
<name>WhizBang Ultra Word Processor</name>
<description xml:lang="EN">
More words per minute than the competition.
</description>
<description xml:lang="FR">
Plus de mots à la minute que la concurrence.
</description>
<image>wordprocessor.jpg</image>
<price>$799.99</price>
</product>
<product id="1">
<name>Super WhizBang Calculator</name>
<description xml:lang="EN">
Cheap and reliable with power saving.
</description>
<description xml:lang="FR">
Economique et fiable avec économie d'énergie.
</description>
<image>calculator.jpg</image>
<price>$5.99</price>
</product>
<total>$805.98</total>
</shopping-cart>
In general, XML is stricter than HTML:
The first line of Listing 2 is the XML declaration. It identifies the XML version and the character set being used. XML is based on the Unicode character set, which means it supports all alphabets, including Japanese and Chinese characters. Yet most documents need only a subset of the characters in the Unicode set. The document in Listing 2 is based on the ISO-8859-1 character set, also known as Latin-1; this is the default character set for Windows. VIEWING XML IN A BROWSERIn the future, browsers will be able to render XML directly. The Mozilla browser from mozilla.org is a good example of how next-generation browsers will handle XML. In the meantime, it's safer to convert XML to HTML on the server. This gives you the best of both worlds: the site is viewable with the current generation of browsers, but internally it benefits from a clean separation between the processing and the presentation. Because so many people need to convert XML documents to HTML, the W3C has developed XSL. XSL is a standard style sheet language that, among other things, supports conversion from XML to HTML. Listing 3 is an XSL style sheet that converts the shopping cart in Listing 2 to HTML. As you can see, the style sheet is itself an XML document. I won't go into all the glorious details of XSL in this article; a future article will cover more advanced XSL techniques. Listing 3
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0"
xmlns="http://www.w3.org/TR/REC-html40" result-ns="">
<xsl:output method="html"/>
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>WhizBang Shopping Cart</TITLE>
</HEAD>
<BODY>
<P>Your shopping cart contains the following items:</P>
<TABLE BORDER="0">
<TR><TD><B>Nom</B></TD><TD><B>Prix</B></TD></TR>
<xsl:for-each select="shopping-cart/product">
<TR>
<TD><xsl:value-of select="name"/></TD>
<TD><xsl:value-of select="price"/></TD>
<TD>
<FORM ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bshoppingcart%26quot%3B&y=1999 METHOD="POST">
<INPUT TYPE="HIDDEN" NAME="remove">
<xsl:attribute name="VALUE">
<xsl:value-of select="@id"/>
</xsl:attribute>
</INPUT>
<INPUT TYPE="SUBMIT" VALUE="Remove"/>
</FORM>
</TD>
</TR>
</xsl:for-each>
<TR>
<TD>Total</TD>
<TD><xsl:value-of select="shopping-cart/total"/></TD>
</TR>
</TABLE>
<TABLE BORDER="0">
<TR>
<TD><FORM><INPUT TYPE="BUTTON" VALUE="Checkout"/></FORM></TD>
<TD>
<FORM ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bproductlist%26quot%3B%26gt%3B&y=1999
<INPUT TYPE="SUBMIT" VALUE="Shop more"/>
</FORM>
</TD>
</TR>
</TABLE>
EN | <A HREF=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bshoppingcart%3Fxsl%3D%2Fshoppingcart_fr.xsl%26quot%3B%26gt%3BFR%26lt%3B%2FA%26gt%3B&y=1999
</BODY>
</xsl:template>
</xsl:stylesheet>
The elements to notice here are as follows:
<INPUT TYPE="HIDDEN" NAME="remove" VALUE="<xsl:value-of select="@id"/>"> Instead, you have to write <INPUT TYPE="HIDDEN" NAME="remove"> <xsl:attribute name="VALUE"> <xsl:value-of select="@id"/> </xsl:attribute> </INPUT> Here the xsl:attribute element creates the attribute "VALUE" in the INPUT element.PUTTING IT ALL TOGETHERTo achieve the separation we want, servlets need to produce XML documents instead of HTML documents, and they need to apply a style sheet to convert the XML documents to HTML. The style sheet must be easy to replace, so that the responsibilities can be divided as follows:
Obviously, we need to integrate an XSL processor into the servlet. There are several XSL processors that are available free of charge. The main ones are XT by James Clark, LotusXSL from IBM's alphaWorks, and Data Channel's XJParse. I decided to use XT, but you could of course use a different XSL processor. In fact, switching to another processor isn't a lot of work. I also wanted to make the XSL postprocessing as invisible as possible. There was no point in manually invoking the XSL processor in every servlet I wrote. So I created a special servlet, XSServlet, that servlets need to inherit from (instead of from HttpServlet) in order to benefit from XSL postprocessing. XSServlet is shown is Listing 4. It accepts GET and POST requests and forwards them to doGetPost(), a method that the descendants of XSServlet must overwrite. It then applies a style sheet to convert the document to HTML.
Listing 4
Note: The following code sample may contain statements that have been
broken into multiple lines in order to make this page printable. In this
example, semicolons indicate the end of a statement that was originally
written on one line.
As a convenience, A SHOPPING CART SERVLETTo illustrate the use of XSServlet, I've written a simple shopping cart servlet. For the sake of simplicity, the shopping cart doesn't connect to a database or a payment system; instead, it collects product information in a cookie. The product object is defined in Listing 5. A product consists of a name, a description (in English and in French), an image, and a price. The product object's main() method creates a vector of products from a text file and serializes the vector. You'll need to call Product at least once to prepare the vector for the servlet; this effectively replaces a database. The product also has a method to write itself in XML. Listing 5
Note: The following code sample may contain statements that have been
broken into multiple lines in order to make this page printable. In this
example, a semicolon indicates the end of a statement that was originally
written on one line.
The shopping cart itself is actually implemented in two servlets:
Listing 6
Note: The following code sample may contain statements that have been
broken into multiple lines in order to make this page printable. In this
example, a semicolon indicates the end of a statement that was originally
written on one line.
Note: The following code sample may contain statements that have been
broken into multiple lines in order to make this page printable. In this
example, a semicolon indicates the end of a statement that was originally
written on one line.
To add a product to the shopping cart, it suffices to call
These servlets are completely free of formatting aspects. They generate XML documents with the appropriate data, while the formatting is delegated to the style sheets. PRESENTATION: THE STYLE SHEETListing 8 is the style sheet for the list of products in the shop. It doesn't display all the information passed to it by the servlet: it uses only the English description.
Listing 8
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0"
xmlns="http://www.w3.org/TR/REC-html40" result-ns="">
<xsl:output method="html"/>
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>Shop</TITLE>
</HEAD>
<BODY>
<P>Select a product:</P>
<TABLE BORDER="0">
<xsl:for-each select="products/product">
<TR>
<TD>
<B><xsl:value-of select="name"/></B><BR/>
<xsl:value-of select="description[@xml:lang='EN']"/><BR/>
<xsl:value-of select="price"/>
</TD>
<TD><IMG>
<xsl:attribute name="SRC">
<xsl:value-of select="image"/></xsl:attribute>
</IMG></TD>
<TD><FORM ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bshoppingcart%26quot%3B&y=1999 METHOD="POST">
<INPUT TYPE="HIDDEN" NAME="add">
<xsl:attribute name="value"><xsl:value-of select="@id"/>
</xsl:attribute>
</INPUT>
<INPUT TYPE="SUBMIT" VALUE="Buy"/>
</FORM></TD>
</TR>
</xsl:for-each>
</TABLE>
<FORM ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bshoppingcart%26quot%3B%26gt%3B&y=1999
<INPUT TYPE="SUBMIT" VALUE="Shopping cart"/>
</FORM>
EN | <A HREF=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bproductlist%3Fxsl%3D%2Fproductlist_fr.xsl%26quot%3B%26gt%3BFR%26lt%3B%2FA%26gt%3B&y=1999
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
The HTML designer can modify the style sheet with no intervention from the programmer. For example, Listing 9 is a style sheet that does a completely different presentation and also uses the French description. Note the use of the xsl parameter in URLs to switch between the French shop and the English shop; this requires no modification of the servlet.
Listing 9
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0"
xmlns="http://www.w3.org/TR/REC-html40" result-ns="">
<xsl:output method="html"/>
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>La Boutique WhizBang</TITLE>
</HEAD>
<BODY BGCOLOR="orange">
<CENTER><TABLE BGCOLOR="white"><TR><TD><CENTER>
<TABLE BORDER="0">
<xsl:for-each select="products/product">
<TR>
<TD>
<B><xsl:value-of select="name"/></B><BR/>
<xsl:value-of select="description[@xml:lang='FR']"/>
<BR/>
<xsl:value-of select="price"/>
</TD>
<TD><IMG>
<xsl:attribute name="SRC">
<xsl:value-of select="image"/>
</xsl:attribute>
</IMG></TD>
<TD><FORM ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bshoppingcart%26quot%3B&y=1999 METHOD="POST">
<INPUT TYPE="HIDDEN" NAME="xsl"
VALUE="/shoppingcart_fr.xsl"/>
<INPUT TYPE="HIDDEN" NAME="add">
<xsl:attribute name="value">
<xsl:value-of select="@id"/>
</xsl:attribute>
</INPUT>
<INPUT TYPE="SUBMIT" VALUE="Ajouter au panier"/>
</FORM></TD>
</TR>
</xsl:for-each>
</TABLE>
<FORM ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bshoppingcart%26quot%3B%26gt%3B&y=1999
<INPUT TYPE="SUBMIT" VALUE="Votre panier"/>
<INPUT TYPE="HIDDEN" NAME="xsl" VALUE="/shoppingcart_fr.xsl"/>
</FORM>
<A HREF=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bproductlist%26quot%3B%26gt%3BEN%26lt%3B%2FA%26gt&y=1999 | FR
</CENTER></TD></TR></TABLE></CENTER>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
Listing 9 demonstrates how style sheets make it easy to support multiple languages and multiple presentations. Similarly, Listing 10 translates the shopping cart; it's the French equivalent of the shopping cart style sheet introduced in Listing 3. Listing 10
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0"
xmlns="http://www.w3.org/TR/REC-html40" result-ns="">
<xsl:output method="html"/>
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>Votre panier chez WhizBang</TITLE>
</HEAD>
<BODY BGCOLOR="orange">
<CENTER><TABLE BGCOLOR="white"><TR><TD><CENTER>
<TABLE BORDER="0">
<TR><TD><B>Nom</B></TD><TD><B>Prix</B></TD></TR>
<xsl:for-each select="shopping-cart/product">
<TR>
<TD><xsl:value-of select="name"/></TD>
<TD><xsl:value-of select="price"/></TD>
<TD>
<FORM ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bshoppingcart%26quot%3B&y=1999 METHOD="POST">
<INPUT TYPE="HIDDEN" NAME="xsl"
VALUE="/shoppingcart_fr.xsl"/>
<INPUT TYPE="HIDDEN" NAME="remove">
<xsl:attribute name="VALUE">
<xsl:value-of select="@id"/>
</xsl:attribute>
</INPUT>
<INPUT TYPE="SUBMIT" VALUE="Supprimer"/>
</FORM>
</TD>
</TR>
</xsl:for-each>
<TR>
<TD>Total</TD>
<TD><xsl:value-of select="shopping-cart/total"/></TD>
</TR>
</TABLE>
<CENTER><TABLE BORDER="0"><TR>
<TD>
<FORM><INPUT TYPE="BUTTON" VALUE="Passer commande"/></FORM>
</TD>
<TD><FORM ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bproductlist%26quot%3B%26gt%3B&y=1999
<INPUT TYPE="SUBMIT" VALUE="Retourner à la boutique"/>
<INPUT TYPE="HIDDEN" NAME="xsl"
VALUE="/productlist_fr.xsl"/>
</FORM></TD>
</TR></TABLE></CENTER>
<A HREF=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%26quot%3Bshoppingcart%26quot%3B%26gt%3BEN%26lt%3B%2FA%26gt&y=1999 | FR
</CENTER></TD></TR></TABLE></CENTER>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
RUNNING THE EXAMPLEYou'll of course need to compile and install the servlets. You'll also have to execute the product application once, to serialize a list of products. The following is a short text file that you can use to create your first shop. (The lines are folded here for readability; you'd need to use the text file downloaded with the other example files.) WhizBang Ultra Word Processor,More words per minute than the competition., Plus de mots à la minute que la concurrence.,wordprocessor.jpg,799.99 Super WhizBang Calculator,Cheap and reliable with power saving., Economique et fiable avec économie d'énergie.,calculator.jpg,5.99 WhizBang Safest Safe,Choose the authentic WhizBang Safest Safe., Exigez l'original!,safe.jpg,1999.00 Finally, you'll have to define these properties for the servlet: products.filename=properties/products.ser shoppingcart.stylesheet=/shoppingcart_en.xsl productlist.stylesheet=/productlist_en.xsl A CLEAN BREAKOur XML-based solution cleanly separates the presentation from the application logic in servlets, corresponding to the separation of roles between HTML designers and Java developers in real-life projects. Using this technique, both sides can work independently. FURTHER RESOURCES
Write to us and let us know what you think of this article. Many thanks to the participants in Edifrance's XML training, who triggered the thought process that led to the development of XSServlet. Special thanks to Caroline Rose for her superb editorial work. Benoît Marchal is a software engineer and consultant based in Namur, Belgium, who has been working extensively in Java and XML. He runs his own software company, Pineapplesoft. He also likes teaching and writing; his first book, XML by Example, will be published by Que in late 1999. (9.99)
Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use |