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/tags
folder - Directly inside a sub-directory of
WEB-INF/tags
folder - Inside the
META-INF/tags
directory inside aJAR
file that's inside theWEB-INF/lib
folder - Inside a sub-directory of the
META-INF/tags
directory, inside aJAR
file that's inside theWEB-INF/lib
folder
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
tag
directives anywhere in a JSP page.- The exception to this rule is when the tag file contains the
pageEncoding
attribute. 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
tag
directives in a tag file. - Attributes that appear in multiple
tag
directives must have the same value.- The exception to this rule is when using the
import
attribute. When multipleimport
attributes 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 | scriptless empty tagdependant | 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 | false true | 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
include
directives anywhere in a tag file. - You can have multiple
include
directives 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
variable
directives anywhere in a tag file. - You can have multiple
variable
directives 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 | true false | The variable is declared within this tag file. The variable is declared within the calling JSP page. |
scope | NESTED - defaultAT_BEGIN AT_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.