ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


JavaServer Pages, 3rd Edition

JSP 2.0: The New Deal, Part 3

by Hans Bergsten, author of JavaServer Pages, 3rd Edition
04/21/2004

More Flexible JSP Document Format Rules

The JSP specification supports two types of JSP pages: regular JSP pages containing any type of text or markup, and JSP Documents, which are well-formed XML documents; i.e., documents with XHTML and JSP elements. To satisfy the well-formed-ness requirements, JSP directives and scripting elements in a JSP Document must be written with a different syntax than a regular JSP page:

Regular JSP page JSP Document
<%@ page attribute list %> <jsp:directive.page attribute list />
<%@ include file="path" %> <jsp:directive.include file="path" />
<%! declaration %> <jsp:declaration>declaration</jsp:declaration>
<%= expression %> <jsp:expression>expression</jsp:expression>
<% scriptlet %> <jsp:scriptlet>scriptlet</jsp:scriptlet>

Tag libraries are declared as XML namespaces in a JSP Document. For instance, a JSP Document with XHTML template text and JSP actions from the standard and the JSTL core libraries should have an <html> root element with these namespace declarations:

  <html 
    xmlns="http://www.w3c.org/1999/xhtml" 
    xmlns:jsp="http://java.sun.com/JSP/Page" 
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xml:lang="en" lang="en">

Related Reading

JavaServer Pages
By Hans Bergsten

The xmlns attribute sets the default namespace to the XHTML namespace, the xmlns:jsp attribute associates the jsp prefix with elements defined as JSP standard actions, and the xmlns:c attribute associates the c prefix with the elements defined by the JSTL core library.

JSP Documents have been part of the JSP specification from day one, but initially as an optional feature and later with many limitations. JSP 2.0 lifts most of these limitations, making it much easier to work with the combination of XML and JSP.

Prior to JSP 2.0, a JSP Document had to have a <jsp:root> root element, to tell the container what type of JSP page it was. JSP 2.0 removes this limitation by defining new ways to identify a file as a JSP Document. A file is processed as a JSP Document by a JSP 2.0 container if one of these conditions is true:

  1. The request path matches the URL pattern for a web.xml JSP property group declaration with an <is-xml> element set to true. See part two of this series for more on JSP property group declarations.

  2. The request path extension is .jspx, unless this extension matches the URL pattern for a JSP property group declaration with an <is-xml> element set to false. In other words, .jspx is the default extension for JSP Documents, but it can be explicitly disabled by a property group declaration.

  3. The request path extension is either .jsp or matches a URL pattern for a JSP property group declaration and the root element in the file is <jsp:root>.

These new rules make it possible to write a JSP Document as a regular XHTML file (with JSP elements for the dynamic content, of course), for instance, without having to place all content within a <jsp:root> element. You can even use .html as the extension for such files if you create a JSP property group declaration like this:

  ...
  <jsp-config>
    <jsp-property-group>
      <url-pattern>*.html</url-pattern>
      <is-xml>true</is-xml>
    </jsp-property-group>
  </jsp-config>
  ...

New Ways to Generate XML Elements

If you've tried to write JSP Documents with JSP 1.2, you've most likely run into problems dynamically assigning values to XML element attributes. For instance, say you want to set the class attribute of an XML element to the value of a bean property holding the user's style preferences. Your first attempt may look something like this:

  <table class="%= user.getTableClass() %">

This type of Java expression can be used as the attribute value of a JSP action element in a JSP Document, but JSP doesn't recognize this syntax in template text, so it doesn't work as used here.

Using a JSP action element to set the attribute value is also a no-go:

  <table class="<c:out value="${user.tableClass}" />">

This doesn't work because a well-formed XML document mustn't have a less-than (<) character in an element attribute value.

The only way to set a markup element attribute value dynamically with JSP 1.2 and still fulfill the well-formed-ness requirement is with nasty-looking CDATA sections, treating the beginning and the end of the markup element as raw text (wrapped around the dynamically generated value) rather than as markup:

  <jsp:text><!CDATA[<table class="]]></jsp:text>
  <c:out value="${user.tableClass}" />
  <jsp:text><!CDATA[">]]></jsp:text>

JSP 2.0 gives you two simple alternatives for this scenario: use an EL expression in the template text, or use a set of new standard actions to generate the element. With an EL expression, the example can be written like this:

  <table class="${user.tableClass}">

A JSP 2.0 container evaluates EL expressions it encounters in template text as well as in action attributes, so in most cases, this solution fits the bill.

If you can't express the value you want to assign as an EL expression, you can instead build the whole XML element dynamically with three new standard actions and generate the attribute value with any type of JSP code:

  <jsp:element name="table">
    <jsp:attribute name="class">
      <c:out value="${user.tableClass}" />
    </jsp:attribute>
    <jsp:body>
      ...
    </jsp:body>
  </jsp:element>

The <jsp:element> action creates an XML element with the attributes created by nested <jsp:attribute> actions. The attribute value is set to the evaluation result of the <jsp:attribute> body, so you can use custom actions to generate the value, such as the <c:out> action used in this example. Similarly, the element body is set to the evaluation result of a nested <jsp:body> element.

A New Standard Action for XML Declarations

An XML document should have an XML declaration at the very top of the document, possibly followed by a DOCTYPE declaration. You control the generation of these two declarations in JSP 2.0 with the new <jsp:output> standard action.

Unless the JSP Document has a <jsp:root> element as its root element (or represents a tag file, which I'll cover in the next article in this series), the JSP container generates an XML declaration like this by default:

  <? xml version="1.0" encoding="encodingValue" ?>

The value of the encoding attribute is the character encoding specified by the contentType attribute of the JSP page directive, or UTF-8 if you don't specify a character encoding. If you don't want an XML declaration to be generated (maybe because the JSP Document is included in another JSP page), you need to tell the JSP container by including a <jsp:output> action element like this in the JSP Document:

  <jsp:output omit-xml-declaration="true" />

Use the attribute values true or yes to disable the declaration generation, and false or no to enable it.

A DOCTYPE declaration tells an XML parser (such as the one used by a browser) with which Document Type Declaration (DTD) the document is supposed to comply. The parser may use this information to validate that the document contains only the XML elements declared by the DTD. You can't put the DOCTYPE declaration for the generated document in the JSP Document, because then you're saying that the JSP Document itself complies with the DTD. Instead, use the <jsp:output> action to tell the JSP container to add a declaration to the generated response:

  <jsp:output doctype-root-element="html"
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
    doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

  <jsp:directive.page contentType="text/html" />

As used in this example, the <jsp:output> action adds a DOCTYPE declaration for XHTML to the response:

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

I also included a <jsp:directive.page> declaration with a contentType attribute to set to the MIME type for the response to text/html in this example, to tell the browser how to treat the response content. Note that the proper MIME type for XHTML is actually application/xhtml+xml, but some modern browsers (notably Internet Explorer 6) don't recognize it; text/html is an accepted MIME type for XHTML 1.0 that most browsers know how to deal with.

Conclusion

JSP 2.0 makes it a lot easier to write JSP pages as XML documents, as you've seen in this installment. The final article in this series will cover the new features related to custom tag libraries: the new tag file format and the new simple tag API.

If you want to try out the new JSP 2.0 features, I recommend that you use Apache Tomcat 5, one of the first JSP containers to implement the new specification. Tomcat 5 is available at the Jakarta Project site.

Hans Bergsten is the founder of Gefion Software and author of O'Reilly's JavaServer Pages, 3rd Edition.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.