Tag FilesS2C Home « Tag Files

In our final lesson on JSTL 1.2 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:

  1. Directly inside the WEB-INF/tags folder
  2. Directly inside a sub-directory of WEB-INF/tags folder
  3. Inside the META-INF/tags directory inside a JAR file that's inside the WEB-INF/lib folder
  4. Inside a sub-directory of the META-INF/tags directory, inside a JAR file that's inside the WEB-INF/lib folder

Creating A Tag Filego to top of page Top

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 Filego to top of page Top

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.

tomcat tagfiles dep struct

The following screenshot shows the results of running the tagfileonetest.jsp JSP page within the tagfiles folder within Tomcat:

run tagfileonetest

Tag File Implicit Objectsgo to top of page Top

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
applicationjavax.servlet.ServletContextServlets 2.5 Basics - ServletConfig & ServletContext
configjavax.servlet.ServletConfigServlets 2.5 Basics - ServletConfig & ServletContext
outjavax.servlet.jsp.JspWriterThis lesson
pageContextjavax.servlet.jsp.PageContextThis lesson
requestjavax.servlet.http.HttpServletRequestServlets 2.5 Basics - Request & Response
responsejavax.servlet.http.HttpServletResponseServlets 2.5 Basics - Request & Response
sessionjavax.servlet.http.HttpSessionServlets 2.5 Intermediate - Session Management Part 3

application Implicit Objectgo to top of page Top

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 Objectgo to top of page Top

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 Objectgo to top of page Top

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 2.5 - 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 Objectgo to top of page Top

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 Objectsgo to top of page Top

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 Objectgo to top of page Top

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 Directivesgo to top of page Top

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 Directivego to top of page Top

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.
  • 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 multiple import attributes with different values are present the effect is cumulative.
tag Directive Attributesgo to top of page Top

There are eleven tag directive attributes in the JSP 2.1 specification. The following table lists them all along with possible attribute values.

Attribute Name Attribute Value Comments
body-contentscriptless
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.
descriptionStringA string description of this tag.
display-nameStringA short name to be displayed by XML tools which defaults to the tag file name without the file extension part.
dynamic-attributesMapA scoped attribute which contains a Map object with the names and values of the dynamic attributes.
exampleStringSpecifies a description of an example of this tag file.
importJava 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.
isELIgnoredfalse
true
Indicates whether EL expressions are ignored or recognized for this tag file.
The default value varies depending on the web.xml version
languageJava - defaultDefaults to Java which is the only valid value in the JSP 2.1 specification.
large-iconContext relative path to a large image to be used by XML tools.
pageEncodingISO-8859-1 defaultSpecifies the character encoding for this JSP page.
smalle-iconContext relative path to a small image to be used by XML tools.
tag Directive Examplesgo to top of page Top

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 Directivego to top of page Top

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 Attributesgo to top of page Top

There is one include directive attribute in the JSP 2.1 specification. The following table lists this along with possible attribute values.

Attribute Name Attribute Value Comments
fileurlThe 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 Directivego to top of page Top

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 Attributesgo to top of page Top

There are two taglib directive attribute in the JSP 2.1 specification. The following table lists these along with possible attribute values.

Attribute Name Attribute Value Comments
uriuriThe 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.
tagdiruriThe 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.
prefixStringPrefix that will be used to identify this tag within the tag file.

The attribute Directivego to top of page Top

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 Attributesgo to top of page Top

There are six attribute directive attribute in the JSP 2.1 specification. The following table lists these along with possible attribute values.

Attribute Name Attribute Value Comments
nameStringThe name for the attribute which must be unique within this tag file.
requiredfalse - default
true
Defaults to false indicating this attribute is not required.
true indicates this attribute is required.
fragmentfalse - default
true
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.
rtexprvaluetrue - default
false
Defaults to true indicating this attribute may be dynamically allocated at runtime.
false indicates this attribute is a string.
typeString - defaultThe object type of this attribute.
descriptionStringA description of this attribute.

The variable Directivego to top of page Top

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 Attributesgo to top of page Top

There are seven variable directive attribute in the JSP 2.1 specification. The following table lists these along with possible attribute values.

Attribute Name Attribute Value Comments
name-givenStringThe 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-attributeStringA 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.
aliasStringLocally scoped attribute holding variable value.
variable-classString - defaultThe object type of this variable.
declaretrue
false
The variable is declared within this tag file.
The variable is declared within the calling JSP page.
scopeNESTED - default
AT_BEGIN
AT_END
Scope of the defined scripting variable.
descriptionStringA description of this variable.

doBody Standard Actiongo to top of page Top

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
varjava.lang.StringName 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.
varReaderjava.io.ReaderName 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.
scopepage - default
request
session
application
Scope of the resultant variable.

invoke Standard Actiongo to top of page Top

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
fragmentStringName used to identify the fragment to use during this tag files execution.
varjava.lang.StringName of scoped attribute within which to store the output from the execution of the fragment.
The var attribute is mutually exclusive with the varReader.
varReaderjava.io.ReaderName of scoped attribute within which to store the output from the execution of the fragment.
The varReader attribute is mutually exclusive with the var.
scopepage - default
request
session
application
Scope of the resultant variable.

Creating Another Tag Filego to top of page Top

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 Filego to top of page Top

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.

tomcat tagfilestwo dep struct

The following screenshot shows the results of running the tagfileonetest.jsp JSP page within the tagfiles folder within Tomcat:

run tagfiletwotest

Lesson 9 Complete

In our final lesson on JSTL 1.2 we looked at Tag Files.

What's Next?

This is the end of the JSTL 1.2 lessons, in the next section our first lesson on JavaServer Pages 2.2 is about the JSP 2.2 specification.

go to home page Homepage go to top of page Top