Tag FilesS2C Home « Tag Files
In our final lesson on JSTL we look at tag files, which allow us to create custom actions for script free JSP pages, much like we have seen in the Creating Our Own Custom Tags and EL Functions lessons. Much like custom tags and EL functions, tag files promote separation of concerns by keeping the business logic apart from the presentation. So why do we need yet another method of creating a custom actions? There are several reasons why we may want to use tag files for developing new software, instead of custom tags or EL functions, as outlined below:
- With tag files there is no need to precompile tag handlers as you have to with custom tags, or a Java class when using an EL function; tag files get compiled the first time they are invoked.
- There is no need for a Tag Library Descriptor (TLD) when using tag files as the name of the tag file is the same as the custom action it represents.
- Tag files can be written completely in JSP syntax meaning page designers with no Java experience can create them.
These are compelling reasons for developing our custom actions using tag files but what does the container do with a tag file when compiling it. How tag files are interpreted or translated depends on the container used,
in Tomcat tag files get translated into simple tag handlers that implement the javax.servlet.jsp.tagext.SimpleTag interface, so we get all the benefits of tag handlers without the extra deployment work.
We mentioned above that tag files can be completely written in JSP syntax which inevitably means that tag files end up looking like JSP pages and the similarities don't end there. Just like JSP pages tag files have their
own set of implicit objects, tag file directives and can include scripts, standard and custom actions and EL expressions. What differentiates a tag file from a JSP page is the tag directive as well as the
tag or tags file extension. Just like JSP pages tag files can also include other resources and these files have the tagf extension.
The container and any JSP pages that want to make use of tag files need a way to locate the tag file in question and this is achieved by deploying the tag file into certain places within our deployment file structure. The container will search in several places as outlined below so make sure that any tag files you create are in one of the locations listed below:
- Directly inside the
WEB-INF/tagsfolder - Directly inside a sub-directory of
WEB-INF/tagsfolder - Inside the
META-INF/tagsdirectory inside aJARfile that's inside theWEB-INF/libfolder - Inside a sub-directory of the
META-INF/tagsdirectory, inside aJARfile that's inside theWEB-INF/libfolder
Creating A Tag FileTop
Tag files use the tag directive which is very similar to the page directive used by JSP pages, more on directives a bit later in the lesson. For now we have enough information to create our
first tag file which is called tagfileone.tag and which has been placed directly inside the WEB-INF/tags folder of our web application called tagfiles.
<%@ tag import="java.util.Date, java.text.DateFormat" %>
<%
Date now = new Date();
DateFormat dfm = DateFormat.getDateInstance(DateFormat.SHORT);
out.println(dfm.format(now));
%>
Using A Tag FileTop
When we want to use a tag file within our JSP pages we use the taglib directive which can reference either a relative path of the context root or an absolute path that points to the location of the tag
file within one of the directories where the container looks for tag files as mentioned above.
The following code example shows a JSP page called tagfileonetest.jsp that uses the tag file tagfileone.tag we wrote above. Remember that no TLD is required as when using tag files the name
of the tag file is the same as the custom action it represents, which in this case is tagfileone.
<%@ taglib tagdir="/WEB-INF/tags" prefix="tf" %>
<!DOCTYPE html>
<html>
<head><title>Testing Our First Tag File</title></head>
<body>
<h1>Testing Our First Tag File</p>
<p>Date in short format is: <tf:tagfileone/></p>
</body>
</html>
This screenshot shows file structure within Tomcat folder c:\apache-tomcat-6.0.37\webapps\tagfiles for the above entities.
The following screenshot shows the results of running the tagfileonetest.jsp JSP page within the tagfiles folder within Tomcat:
Tag File Implicit ObjectsTop
With tag files we have access to implicit objects which are similar to those discussed in the JSP Implicit Objects lesson. The table below shows all the implicit objects available to tag file authors and links to the lessons in which the various types involved are discussed:
| Implicit Object | Type | Lesson |
|---|---|---|
application | javax.servlet. | Servlets Basics - ServletConfig & ServletContext |
config | javax.servlet. | Servlets Basics - ServletConfig & ServletContext |
out | javax.servlet. | This lesson |
pageContext | javax.servlet. | This lesson |
request | javax.servlet. | Servlets Basics - Request & Response |
response | javax.servlet. | Servlets Basics - Request & Response |
session | javax.servlet. | Servlets Intermediate - Session Management Part 3 |
application Implicit ObjectTop
The application implicit object is of type javax.servlet.servletContext and saves you the trouble of creating your own application scoped variable. You can use the application
implicit object anywhere you would use the ServletContext object in a regular Servlet such as setting application wide atributes.
The following code snippet shows some application implicit object use:
<%-- Using application Implicit Object --%>
<% application.setAttribute("name", "joe"); %>
<%= application.getAttribute("name") %>
For more information on the javax.servlet.ServletContext interface and the methods available take a look at the >ServletContext Interface section.
config Implicit ObjectTop
The config implicit object is of type javax.servlet.servletConfig and can be used to access ServletConfig methods for such things as getting initialisation parameters.
The following code snippet shows some config implicit object use:
<%-- Using config Implicit Object --%>
<%= config.getInitParameter("email") %>
For more information on the javax.servlet.ServletConfig interface and the methods available take a look at the ServletConfig Interface section.
jspContext Implicit ObjectTop
The jspContext implicit object is of type javax.servlet.jsp.jspContext and is the container's implementation of the tag file page in question.
The jspContext implicit object also allows access to page scope which is the narrowest of the four scopes available and attributes stored within this scope are only available within the same tag file itself.
For a refresher on using the request, session and context scopes see the Servlets - Attributes and Scope lesson.
You can also work with attributes from page scope, or one of the other scopes, using one of the overloaded attribute methods. The following code snippet shows signatures for the overloaded getAttribute() method:
// Page scope attribute
public abstract Object getAttribute(String name)
// Named scope attribute
public abstract Object getAttribute(String name, int scope)
If no scope is specified then attributes from the page scope will be actioned. The following code snippet shows some jspContext implicit object use:
<%-- Using jspContext Implicit Object --%>
<%
jspContext.setAttribute("name", "charlie", 4);
jspContext.setAttribute("name", "marlie");
out.print("Application attr: " + jspContext.getAttribute("name", 4));
out.print(" | Page attr: " + jspContext.getAttribute("name"));
%>
out Implicit ObjectTop
The out implicit object is of type javax.servlet.jsp.JspWriter and not java.io.PrintWriter as you might expect, although the javax.servlet.jsp.JspWriter class does
emulate many of the features of the java.io.PrintWriter class. The main reason that the out implicit object uses javax.servlet.jsp.JspWriter is for that classes buffering capabilities
which are functionally similar to those of the java.io.BufferedWriter class.
The following code snippet shows some out implicit object use:
<%-- Using application Implicit Object --%>
<%! String strArray[] = {"one", "aa", "c", "rt", "je"}; %>
<% out.print("Value of position 5 (index 4) : " + strArray[4]); %>
request and response Implicit ObjectsTop
The request and response implicit objects are of types javax.servlet.http.HttpServletRequest and javax.servlet.http.HttpServletResponse respectively in the vast majority of cases.
Of course there is nothing to stop you as a coder from creating a JSP page for a protocol other than HTTP by using the javax.servlet.jsp.HttpJspPage interface, that extends the javax.servlet.jsp.JspPage
interface, which extends the javax.servlet.Servlet interface. So if for any reason you wanted to write non-HTTP JSP pages, you would implement the javax.servlet.jsp.JspPage interface for
the protocol required and this would still get translated into a Servlet. In this scenario your request & response implicit objects are still passed but would be of types javax.servlet.ServletRequest and javax.servlet.ServletResponse respectively.
The following code snippet shows some request & response implicit object use:
<%-- Using request Implicit Object --%>
<%= request.getHeader("user-agent") %>
<%-- Using response Implicit Object --%>
<%= response.containsHeader("content-type") %>
For more information on the javax.servlet.http.HttpServletRequest interface and the methods available take a look at the ServletRequest Overview
and HttpServletRequest Overview sections.
For more information on the javax.servlet.http.HttpServletResponse interface and the methods available take a look at the ServletResponse Overview
and HttpServletResponse Overview sections.
session Implicit ObjectTop
The session implicit object is of type javax.servlet.http.HttpSession and can be used to access HttpSession methods to do all the things you would generally do when tracking sessions. Unlike
normal Servlets where we have to explicitly create session objects for our servlets this is done implicitly and so every page always comes with a HttpSession object. If your page doesnt require sessions
then you have to turn off session creation using a page directive.
The following code snippet shows some session implicit object use:
<%-- Using session Implicit Object --%>
<% session.setAttribute("name", "joe"); %>
<%= session.getAttribute("name") %>
<% session.invalidate(); %>
For more information on the javax.servlet.http.HttpSession interface and the methods available take a look at the HttpSession Interface section.
Tag File DirectivesTop
There are five tag file directives, these being tag, include, taglib, attribute and variable each of which we will look at in more detail in the following subsections.
The tag DirectiveTop
The tag directive is used to instruct the translator about characteristics of the page it is contained within and is akin to the page directive used with JSP pages. The tag directive syntax follows:
<%@tag attribute1="value1" attribute2="value2" ... attributen="valuen" %>
There are a few basic rules and exceptions when using the tag directive:
- You can place
tagdirectives anywhere in a JSP page.- The exception to this rule is when the tag file contains the
pageEncodingattribute. If this attributes is present it must precede any template data and data sent using Java code. This makes sense as we need to set a type prior to sending content to the browser.
- The exception to this rule is when the tag file contains the
- You can have multiple
tagdirectives in a tag file. - Attributes that appear in multiple
tagdirectives must have the same value.- The exception to this rule is when using the
importattribute. When multipleimportattributes with different values are present the effect is cumulative.
- The exception to this rule is when using the
tag Directive AttributesTop
There are eleven tag directive attributes in the jsp specification. The following table lists them all along with possible attribute values.
| Attribute Name | Attribute Value | Comments |
|---|---|---|
body-content | scriptlessemptytagdependant | Defaults to scriptless specifying scripting is invalid.
Setting this to empty means there is no body.Setting this to tagdependant sets body content dependant upon tag. |
description | String | A string description of this tag. |
display-name | String | A short name to be displayed by XML tools which defaults to the tag file name without the file extension part. |
dynamic-attributes | Map | A scoped attribute which contains a Map object with the names and values of the dynamic attributes. |
example | String | Specifies a description of an example of this tag file. |
import | Java type(s) | Specifies the types that are available to this tag file. To import an entire package use the '*' wildcard type. To import multiple types, delimit each with a comma. |
isELIgnored | falsetrue | Indicates whether EL expressions are ignored or recognized for this tag file. The default value varies depending on the web.xml version |
language | Java - default | Defaults to Java which is the only valid value in the jsp specification. |
large-icon | Context relative path to a large image to be used by XML tools. | |
pageEncoding | ISO-8859-1 default | Specifies the character encoding for this JSP page. |
smalle-icon | Context relative path to a small image to be used by XML tools. |
tag Directive ExamplesTop
The following code snippet shows different examples of tag directive attributes and values:
<%-- Set content type --%>
<%@ tag description="this tag ..." %>
<%-- Class import --%>
<%@ tag import="java.util.List" %>
<%-- Package import --%>
<%@ tag import="java.util.*" %>
<%-- Multiple imports delimited by commas --%>
<%@ tag import="java.util.Date, java.util.List" %>
<%-- Multiple attributes --%>
<%@ tag import="java.util.Date" description="this tag ..." %>
<%-- Multiple tag directives --%>
<%@ tag import = "java.util.Date" %>
<%@ tag isELIgnored="true" %>
The include DirectiveTop
The include directive is used to insert the contents of another file into this tag file and works exactly the same way as for JSP pages. This is achieved during translation when the include directive is replaced with the
contects of the included file. This is useful when the contents of the included file are required within different programs or even different places within the same tag file.
The include directive syntax follows:
<%@ include file="url" %>
There are a few basic rules when using the include directive:
- You can place
includedirectives anywhere in a tag file. - You can have multiple
includedirectives in a tag file.
include Directive AttributesTop
There is one include directive attribute in the jsp specification. The following table lists this along with possible attribute values.
| Attribute Name | Attribute Value | Comments |
|---|---|---|
file | url | The URL path can begin with a forward slash making it relative to the context root of the application, or not making it relative to the tag file. |
The taglib DirectiveTop
The taglib directive is used to access and use custom tags within your tag file of from a calling JSP page.
The taglib directive syntax follows:
<%@ taglib tagdir="pathToTagLibrary" prefix="tagPrefix" %>
taglib Directive AttributesTop
There are two taglib directive attribute in the jsp specification. The following table lists these along with possible attribute values.
| Attribute Name | Attribute Value | Comments |
|---|---|---|
uri | uri | The URL path can begin with a forward slash making it relative to the context root of the application, or not making it relative to the Tag Library Descriptor. The uri attribute is mutually exclusive with the tagdir. |
tagdir | uri | The URL path can begin with a forward slash making it relative to the context root of the application, or not making it relative to the tag file. The tagdir attribute is mutually exclusive with the uri. |
prefix | String | Prefix that will be used to identify this tag within the tag file. |
The attribute DirectiveTop
The attribute directive allows usage of attributes within our tag files and is the same as the attribute element that we have used for our customs tags via the Tag Library Descriptor.
The attribute directive syntax follows:
<%@ attribute attribute1="value1" attribute2="value2" ... attributen="valuen" %>
attribute Directive AttributesTop
There are six attribute directive attribute in the jsp specification. The following table lists these along with possible attribute values.
| Attribute Name | Attribute Value | Comments |
|---|---|---|
name | String | The name for the attribute which must be unique within this tag file. |
required | false - defaulttrue | Defaults to false indicating this attribute is not required.true indicates this attribute is required. |
fragment | false - defaulttrue | Defaults to false indicating this attribute is to be evaluated by the container.true indicates this attribute is to be evaluated by the tag handler. |
rtexprvalue | true - defaultfalse | Defaults to true indicating this attribute may be dynamically allocated at runtime.false indicates this attribute is a string. |
type | String - default | The object type of this attribute. |
description | String | A description of this attribute. |
The variable DirectiveTop
The variable directive allows us to define details of a variable in a tag file to be accessible from the calling JSP page and is akin to the variable attribute used in the tag library descriptor.
We can have multiple variable directives in a tag file thus allowing multiple values to be passed across to the calling JSP page.
The variable directive syntax follows:
<%@ variable attribute1="value1" attribute2="value2" ... attributen="valuen" %>
There are a few basic rules when using the variable directive:
- You can place
variabledirectives anywhere in a tag file. - You can have multiple
variabledirectives in a tag file.
variable Directive AttributesTop
There are seven variable directive attribute in the jsp specification. The following table lists these along with possible attribute values.
| Attribute Name | Attribute Value | Comments |
|---|---|---|
name-given | String | The specified variable name that will be available for use by any scripting or EL expressions in the calling JSP page and which must be unique within this tag file. The name-given
attribute is mutually exclusive with the name-from-attribute. |
name-from-attribute | String | A variable attribute value that will be populated dynamically from the specified attribute when the tag file is invoked and made available for
use by any scripting or EL expressions in the calling JSP page and which must be unique within this tag file. The name-from-attribute attribute is mutually exclusive with the name-given. |
alias | String | Locally scoped attribute holding variable value. |
variable-class | String - default | The object type of this variable. |
declare | truefalse | The variable is declared within this tag file. The variable is declared within the calling JSP page. |
scope | NESTED - defaultAT_BEGINAT_END | Scope of the defined scripting variable. |
description | String | A description of this variable. |
doBody Standard ActionTop
The doBody standard action is the first of the two standard actions that relate solely to tag files. The doBody standard action can have attributes as described in the table below. These attributes
allow the output of the tag execution to be placed within a scoped variable. If no attributes are used used then the output of the tag execution is written to the JspWriter of the calling JSP page.
| Attribute Name | Attribute Value | Comments |
|---|---|---|
var | java.lang.String | Name of scoped attribute within which to store the output from the execution of the tag body. The var attribute is mutually exclusive with the varReader. |
varReader | java.io.Reader | Name of scoped attribute within which to store the output from the execution of the tag body. The varReader attribute is mutually exclusive with the var. |
scope | page - defaultrequest session application | Scope of the resultant variable. |
invoke Standard ActionTop
The invoke standard action is the second of the two standard actions that relate solely to tag files. The invoke standard action can have attributes as described in the table below and is
similar in concept to the doBody standard action. The invoke standard action can be used in a tag file to invoke an attribute standard action whose fragment attribute
has been set true and the invocation can occur multiple times within the tag file.
| Attribute Name | Attribute Value | Comments |
|---|---|---|
fragment | String | Name used to identify the fragment to use during this tag files execution. |
var | java.lang.String | Name of scoped attribute within which to store the output from the execution of the fragment. The var attribute is mutually exclusive with the varReader. |
varReader | java.io.Reader | Name of scoped attribute within which to store the output from the execution of the fragment. The varReader attribute is mutually exclusive with the var. |
scope | page - defaultrequest session application | Scope of the resultant variable. |
Creating Another Tag FileTop
Lets use several of the directives we have seen in this lesson and invoke an attribute fragment so we can see how various parts of a tag file interact. The following tag file is called tagfiletwo.tag
and has been placed directly inside the WEB-INF/tags folder of our web application called tagfiles
<%@ attribute name="bookDetails" fragment="true" %>
<%@ variable name-given="bookAuthor" %>
<%@ variable name-given="bookTitle" %>
<%@ variable name-given="bookISBN" %>
<%
jspContext.setAttribute("bookAuthor", "Kevin Charles");
jspContext.setAttribute("bookTitle", "Things to do before your 60");
jspContext.setAttribute("bookISBN", "1234-5678-9012");
%>
<jsp:invoke fragment="bookDetails">
Using The Tag FileTop
When we want to use a tag file within our JSP pages we use the taglib directive which can reference either a relative path of the context root or an absolute path that points to the location of the tag
file within one of the directories where the container looks for tag files as mentioned above.
The following code example shows a JSP page called tagfiletwotest.jsp that uses the tag file tagfiletwo.tag we wrote above. Remember that no TLD is required as when using tag files the name
of the tag file is the same as the custom action it represents, which in this case is tagfiletwo.
<%@ taglib tagdir="/WEB-INF/tags" prefix="tftwo"%>
<!DOCTYPE html>
<html>
<head><title>Testing Our Second Tag File</title></head>
<body>
<h1>Testing Our Second Tag File</h1>
<tftwo:tagfiletwo>
<jsp:attribute name="bookDetails">
<table>
<tr style="background:yellow"><td>Book Author</td><td>${bookAuthor}</td></tr>
<tr style="background:green"><td>Book Title</td><td>${bookTitle}</td></tr>
<tr style="background:cyan"><td>Book ISBN</td><td>${bookISBN}</td></tr>
</table>
</jsp:attribute>
</tftwo:tagfiletwo>
</body>
</html>
This screenshot shows file structure within Tomcat folder c:\apache-tomcat-6.0.37\webapps\tagfiles for the above entities.
The following screenshot shows the results of running the tagfileonetest.jsp JSP page within the tagfiles folder within Tomcat:
Lesson 9 Complete
In our final lesson on JSTL we looked at Tag Files.
What's Next?
This is the end of the JSTL lessons, in the next section our first lesson on JavaServer Pages 2.2 is about the JSP 2.2 specification.