Sun Microsystems created Java servlet technology, and it was good. (See Resources.) All subsequent Java server techniques have been based on servlets. And while nobody argues against servlets' efficacy, the debate rages on over which follow-on technologies (if any) are best for solving Web-based presentation problems. Those problems include:
- Separating presentation (HTML) from content generation code (code that accesses databases and generates XML documents, result-set data structures, Java object data, and so on)
- Maintaining consistency with the modern component-based software construction paradigm, to leverage modularization and code reuse
- Reuse and nesting of markup in different page contexts (templating)
- Minimizing the learning curve for new scripting languages and tag vocabularies, and maximizing their compatibility with HTML authoring tools
Combining code and presentation obfuscates the design intent behind both elements, and encourages the designer/programmer to design the software and the page simultaneously -- two very distinct activities. Or, even worse, if separate page designers and programmers work on the site, they won't be able to work simultaneously without breaking each other's code.
Disregard for object-oriented software-component construction and the inability to reuse and nest markup blocks are closely related to the blending of markup with content generation code. Mingling code and markup means specific content generation code is hardwired to specific formatting. That limits your ability to build encapsulated objects for generating content. There is a similar problem for presentation components (templates): if the presentation is mingled with the content generation code, you have little chance of reusing or nesting page elements.
The techniques discussed in this article (besides raw servlets) enhance HTML documents by employing scripting languages, sets of custom markup tags, and automatic Java class generation to help solve the first three problems in the above list. If it is too difficult for nonprogrammers to learn to use these tools, then we must still deal with the problem of programmers being forced to become page designers. Page designers rely on HTML authoring tools, so new tags and scripts should be as friendly to authoring tools as possible.
I did not include performance and scalability in the list of problems, but they are primary issues. Commercial servlet engines generally provide excellent performance and most now offer high-end scalability features, so most servlet-based presentation solutions will perform and scale well. However, some techniques add loads to the server, such as realtime XML parsing and XSL processing. The performance-analysis details of adding those loads are beyond the scope of this article.
The following discussion describes some servlet-based Webpage-presentation techniques, with respect to the above list of problems. Specifically, this article discusses the main techniques for solving presentation problems by focusing on a small, representative sampling of systems that implement them. A raft of servlet-based templating engines and server-side Java application frameworks are available or in development, but are not mentioned here.
Servlets are a vast improvement on the heavyweight process-per-request programming model used by CGI scripts. The servlet model of handling requests using lightweight Java threads (one per client request) is much more efficient. The mini-programs also add a degree of persistence across requests, without using a formal database or disk storage. Servlets remain the mainstay on the Java server for managing client requests.
However, trading in CGI scripts for Java servlets does not address the problem of the HTML deeply embedded within the code -- be it Perl or Java -- that generates the page content. Servlets are commonly used to dynamically generate HTML pages for interactive Websites by aggregating the HTML text and writing it to a
java.io.PrintWriter object. This tedious process couples presentation and content generation. (Perl's text manipulation prowess actually makes it the better language for this.) As a direct result, either the page designer must learn Java programming, or the Java programmer must learn page design.
Building presentation components using raw servlets is conceivable, especially if the design included some mechanism for using and reusing blocks of HTML, into which dynamic content could be embedded at request time. The rest of the techniques rely on the addition of some form of templating to raw servlets. You can consider these as alternatives to a roll-your-own approach to Webpage templates.
Templating is a technique that enhances static HTML documents by adding either scripting code or custom tags, or by automating the creation of Java classes that represent the documents. A template, then, is a reusable piece of enhanced HTML that, through Java manipulation or embedded scripting, can facilitate the runtime inclusion of dynamically generated content. The rest of this section briefly describes three exemplary open source templating engines.
WebMacro provides a minimal framework for implementing the Model/View/Controller (MVC) architecture in a Web context. (See Resources for links.) The framework facilitates the mapping of requests to and the execution of templates, and provides them with session information and any business object data they need to access. The scripting language allows the templates to randomly access the business objects. In MVC parlance, the business object data comprise the model, the templates are the views, and the code that maps the requests to and executes the templates is the controller.
WebMacro's core feature is its support for a simple scripting language (with a syntax resembling Perl's). Actually, WebMacro's creator, Justin Wells, calls it a "templating language" to distinguish it from a full-fledged scripting language. The language supports:
- Primitive branching
- Iterating through lists of objects
- Access to data generated by external Java objects
- Inclusion of other template files or any text file (static include)
- Parsing of template files (dynamic include)
- Local variables
WebMacro uses a deep Java reflection (see Resources) process to ascertain the topography of objects. This gives the templates access to data without the need for a special syntax to declare objects, bind local identifiers to object classes and properties, or get and set properties. A template can simply refer to a deeply embedded field (or a method) with dot-separated identifiers that match the object's field and method identifiers.
The most straightforward way to implement a service using WebMacro is to subclass Webmacro's
WMServlet class and override the
handle() method, which takes a request
Context object and returns a
handle() function implements these steps:
- Use the
WebContextinformation (including the
HttpServletRequestobject) to determine which template to use
- Put any data the selected template needs into the context
- Get the parsed template -- cache it if it's not yet in the cache
- Return the template to WebMacro, which will execute and render it back to the client
WebMacro completely removes HTML from Java code and embeds server-side scripting in the HTML files, transforming them into WebMacro template files. This makes the HTML more complex, and at least marginally reduces the utility of HTML-authoring tools. The added overhead for HTML authors is presumably outweighed by the programmer productivity gained by relieving you of the burden of generating HTML. WebMacro's simple, yet flexible, templating supports template reuse, and the dynamic-include feature supports template nesting.
The addition of a scripting -- sorry, "templating" -- language introduces a learning curve for HTML designers. WebMacro minimizes this problem by keeping the language primitive, but capable enough to handle the types of coding needed in a template.
WebMacro has recently been reimplemented by the Apache Software Foundation's Jakarta project (see Resources), and branded as the "Velocity" subproject.
FreeMarker (see Resources) is remarkably similar to WebMacro. It implements MVC exactly as was described for WebMacro. The main differences are:
- FreeMarker's scripting language is more sophisticated than WebMacro's: it has functions and Boolean expressions
- FreeMarker's scripting language has a more heavyweight syntax
- FreeMarker's template-caching mechanism has automatic cache updating, so modified templates can be automatically incorporated without bringing down the service
Both systems address the four presentation problems admirably, but WebMacro is better. A templating system's main purpose is to separate programming from presentation, so the benefits of FreeMarker's more sophisticated scripting capabilities are dubious -- especially if you consider presentation problems 1 and 4, listed previously. WebMacro's lack of "powerful" scripting features is an advantage, not a weakness.
FreeMarker's cache-updating feature is primitive, and both systems' caching is based on a filesystem. Neither system implements a database-caching mechanism, although both allow you to add one.
I've contrasted the way raw servlets support dynamic pages -- by embedding HTML inside the Java code -- with the way the WebMacro and FreeMarker templating engines embed some form of scripting inside HTML files. XMLC's approach is completely different. (See Resources.) XMLC is a specialized Java compiler for HTML (or XML) template files. That's right, XMLC compiles pure HTML files into Java class files, with a unique class for each unique HTML template.
XMLC works by leveraging HTML's ID attribute in conjunction with the XML Document Object Model (DOM). (IDs are document-wide unique identifiers.) HTML templates are compiled into Java classes; each class contains a DOM representation of the document. The classes have access methods for all HTML elements with ID attributes. The Java code that manipulates the documents uses the access methods to modify the template by adding to or changing the corresponding elements. XMLC also uses the
SPAN element to insert and modify text, and the
CLASS attribute to group element sets.
The template classes implement the
org.enhydra.xml.xmlc.html.HTMLObject interface and extend
org.enhydra.xml.xmlc.html.HTMLObjectImpl. If you try XMLC, note that the supposedly XMLC-generated source code that appears in the bundled tutorial will not work because the classes fail to extend
HTMLObjectImpl. The actual XMLC-generated code does it correctly. (See Resources for a link to the XMLC Website.) Servlet code that populates the template objects follows these steps:
- Instance the template object that corresponds to the request being handled
- Add dynamic content to the template object's DOM document by using the access methods
- Call the
HTMLObject.toDocument()method to retrieve the resulting text response
XMLC was once distributed as part of the Enhydra open source Java/XML application server (see Resources); because of its popularity, it is now a standalone project. A new project at Enhydra.org, called Rocks Presentation Framework (see Resources), is underway; it is scheduled for an alpha release in late November. Rocks is one of several projects attempting to design and implement a comprehensive MVC presentation framework; it is built around XMLC.
One of the XMLC project's design goals is stated in the XMLC User's Manual:
The HTML pages will remain a valid mockup of the site. The designer may continue to evolve the pages as needed and updates can be passed to the programmer without losing the information necessary to generate dynamic pages. Since the HTML pages never contain anything but legal HTML, this falls out naturally.
This is a powerful concept. It means that the same HTML files the designer uses for a mockup become the presentation templates and remain valid throughout the project's life. It also means the designers can work independently for long periods, and only when they're satisfied with a large set of mockup changes must they deliver it to the programmers. Although even minor changes to HTML files require recompiling, XMLC has a nice auto-recompilation feature that lets you configure your application to always use the latest templates without having to restart it.
XMLC does the best job (of the three templating engines discussed) of separating code from presentation because the templates are pure HTML, with absolutely no code added. This completely solves the learning-curve problem. The HTML author only needs to learn how to use the
CLASS attributes and the
SPAN element -- all standard HTML features. This also allows full leveraging of HTML authoring tools.
One problem with XMLC is its lack of support for nesting templates. The Rocks Presentation Framework may add that support.
JavaServer Pages (JSP)
JavaServer Pages (see