JavaServer Faces (JSF) applications require some sort of display technology, such as JavaServer Pages. One of the cool things about JSP is the ability to extend it with custom tags. A custom tag is a special XML element backed by Java code, that can be used in addition to standard JSP elements or HTML elements. A custom tag can do almost anything: display the value of variables, parse XML, conditionally display parts of a page, access a database, and so on (whether or not anyone should be doing all of these things with JSP tags is a question for another day...). Their main purpose is to keep Java code out of the pages and allow frontend developers to use simple, familiar tags instead. A group of related custom tags forms a tag library.
JSF is integrated with JSP using custom tags. All of the JSF tags we've shown so far in this book —
<f:view>, and so on—are custom tags. JSF implementations must support JSP with custom tag libraries that provide access to all of the standard components, renderers, validators, and converters. These libraries (included in the JSF JARs) are listed in the table below.
JSF custom tag libraries
All of the tags in these libraries must be named and implemented in a specific manner. This way, your JSP-based applications are guaranteed to be portable across different JSF implementations. Most IDEs can be used with JSP.
For the most part, using JSF with JSP is just a matter of using the JSF custom tag libraries. There are, however, some nuances you should be aware of, like using JSP includes.
Using JSP includes
One of JSP's key features is the ability to integrate content from multiple JSPs into a single page. This is often used for fun tasks like including a header or a footer. JSP supports two types of includes: dynamic and static. Dynamic includes (performed with the
<jsp:include> tag or the JSTL
<c:import> tag) access a resource at runtime. In this case, control is forwarded to the included JSP. The response from the included JSP is merged with the response sent back from the calling page. When changes are made to a dynamically included page, they automatically show up in all calling pages.
Static includes integrate the resource at translation time—when the page is morphed into Java code and compiled. The contents of the source page are essentially copied into the calling page. Changes made to the included content generally aren't automatically noticed by calling pages because they already have their own copy of the content. They have to be "touched" so that they can be recompiled with the new content. (JSP 2.0's implicit includes, which can be configured in
web.xml, are processed like static includes.)
JSF works with both types of JSP includes. For dynamic includes, there are two requirements:
- Included pages must be enclosed in a JSF
<f:subview>core tag. This tag can either be in the included page or around the include statement.
- All template text and non-JSF tags inside included pages should be enclosed with the JSF
So, let's say we had the following snippet in a JSP page:
<f:view> ... <jsp:include page="foo.jsp"/> ... </f:view>
Foo.jsp might look like this:
<f:subview> <h:outputText value="heyah!"/> ... <f:verbatim> <b>Template text.</b> <customtag:dothis/> </f:verbatim> </f:subview>
As you can see, the entire included page is enclosed in an
<f:subview> tag, and all non-JSF tags and template text are enclosed in an
<f:verbatim> tag. Alternatively, we could move the
<f:subview> tag into the first page, around the
Using a static include is much simpler. There are no restrictions—you don't even have to use the
In the last example, we showed a fictitious custom tag,
<customtag:dothis>, that performs some random task. This underscores an important point: you can use JSF with other JSP custom tags.
Using JSF with JSTL and other JSP custom tags
All of this talk about JSF's custom tag libraries is nice, but what if you have your own custom tags, or third-party ones? Or what if you're using the JSP Standard Tag Library (JSTL), which is a set of standard tags that do all of those neat things we just mentioned? For the most part, you can mix and match them with JSF tags. Faces tags can be nested within other tags and vice versa. Some products, like IBM's WebSphere Application Developer, encourage this approach, while others, like Sun's Java Creator Studio, opt for a pure JSF approach. Oracle's JDeveloper on the other hand, lets you mix and match, but also encourages the pure JSF approach.
Note: Whenever you nest a JSF tag inside a non-JSF custom tag, you must assign the JSF tag a component identifier.
Because JSTL is standard and familiar to many, we'll use it to demonstrate the use of JSF with custom tags. (If you're thirsty for general information on JSTL, check out Shawn Bayern's excellent book, JSTL in Action.) Let's start with the simple example (shown in Listing 1) that mixes and matches some JSTL tags with JSF tags. This code imports both JSF tag libraries and the core JSTL tag libraries.
Listing 1. Mixing JSTL tags with JSF tags
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head> <title>JSF in Action: JSTL Example 1 - Mixing JSF with other custom tags </title> </head> <body bgcolor="#FFFFFF"> <f:view> <h1> <h:outputText value="Example of using JSF tags with other custom tags"/> </h1> <p> <b> <c:out value="Here's the value of your web.xml (don't do this at home):"/> </b> <blockquote> <f:verbatim> <c:import url="WEB-INF/web.xml"/> </f:verbatim> </blockquote> </p> </f:view> </body> </html></code>