Taglibs are wonderful components available since J2EE 1.3. They enable you, as developer:
- to refrain from using too much scriptlets (free-form Java code) in your Java Server Pages,
- to have a library of reusable components that can be distributed to all your projects.
Both are very important in the enterprise as of now. For example, as an architect, you can disallow the use of scriptlets altogether and then provide taglibs to restrain what can be done on the page. Such policies are not uncommon and can be enforced by quality code checkers. It prevents fresh-out-of-school developers to call JDBC code in the JSP, thus destroying your precicous Model View Controller model.
Taglibs have a big drawback, though: they are standard Java classes that inherit the right class (javax.servlet.jsp.tagext.Tag
or javax.servlet.jsp.tagext.SimpleTag
).
Thus, their content must be written to the JspWriter.
In that, they are very similar to Servlets: they cannot be designed by a graphist and you must provide an servlet engine to see their output.
Servlet have JSP to serve as view, taglibs have tagfiles!
What is a tagfile, anyway? Just put a file with a *.tag extension in your /WEB-INF/tags
directory, and bingo, you have a tagfile.
In order to test the creation of tagfiles, create a hello.tag with the following content: "Hello world".
Then create a JSP and paste the following snippet:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="tag" tagdir="/WEB-INF/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Tag files example</title>
</head>
<body>
<tag:hello />
</body>
</html>
You can already guess the output.
The little magic comes in referencing the tagfile.
We do not use the uri
attribute of the taglib
directive but the tagdir
attribute that tells the application server where we stored our tagfiles.
To call the tagfile, use the prefix as usual and then the name of the file.
No need to use a TLD.
Easy, isn’t it?
To easy…
In fact, this use of tagfiles does not enable reuse.
It is done in the context of a single web application and has not many advantages over use of JSP includes.
To package tagfiles for reuse, you’ll have to move the files from /WEB-INF/tags
to /META-INF/tags
and create a full fledged TLD under /META-INF
:
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd ">
<tlib-version>1.0</tlib-version>
<short-name>tf</short-name>
<uri>http://blog.frankel.ch/examples/tagfiles</uri>
<!-- don't use tagclass -->
<tag-file>
<name>hello</name>
<path>/META-INF/tags/hello.tag</path>
</tag-file>
</taglib>
Now use the taglib in a JSP (don’t forget to use the uri
attribute now).
The result should be the same, but now you have a reusable component per-se.
Of course, writing a string in the output is not very useful.
Like taglibs, tagfiles can accept variables.
It is very easy to do this, because many attributes which are found under the TLD with taglibs are found in the tagfile itself.
Let’s write a tagfile that write today’s date with the format given by the developer:
<%@ tag body-content="empty" %>
<%@ attribute name="format" required="true" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:useBean id="date" class="java.util.Date" />
<fmt:formatDate value="${date}" pattern="${format}" />
Notice the attribute
syntax.
Eclipse project for these examples can be found here.