The Java EE 5 Tutorial

Declaring Tag Variables in Tag Files

Tag attributes are used to customize tag behavior much as parameters are used to customize the behavior of object methods. In fact, using tag attributes and EL variables, it is possible to emulate various types of parameters: IN, OUT, and nested.

To emulate IN parameters, use tag attributes. A tag attribute is communicated between the calling page and the tag file when the tag is invoked. No further communication occurs between the calling page and the tag file.

To emulate OUT or nested parameters, use EL variables. The variable is not initialized by the calling page but instead is set by the tag file. Each type of parameter is synchronized with the calling page at various points according to the scope of the variable. See Variable Synchronization for details.

To declare an EL variable exposed by a tag file, you use the variable directive. A TLD has an analogous variable element (see Declaring Tag Variables for Tag Handlers). Table 8–4 lists the variable directive attributes.

Table 8–4 variable Directive Attributes

Attribute 

Description 

description

(optional) An optional description of this variable. Defaults to no description. 

name-given | name-from-attribute

Defines an EL variable to be used in the page invoking this tag. Either name-given or name-from-attribute must be specified. If name-given is specified, the value is the name of the variable. If name-from-attribute is specified, the value is the name of an attribute whose (translation-time) value at the start of the tag invocation will give the name of the variable.

Translation errors arise in the following circumstances: 

1. Specifying neither name-given nor name-from-attribute or both.

2. If two variable directives have the same name-given.

3. If the value of a name-given attribute of a variable directive is equal to the value of a name attribute of an attribute directive or the value of a dynamic-attributes attribute of a tag directive.

alias

Defines a variable, local to the tag file, to hold the value of the EL variable. The container will synchronize this value with the variable whose name is given in name-from-attribute.

Required when name-from-attribute is specified. A translation error results if used without name-from-attribute.

A translation error results if the value of alias is the same as the value of a name attribute of an attribute directive or the name-given attribute of a variable directive.

variable-class

(optional) The name of the class of the variable. The default is java.lang.String.

declare

(optional) Whether or not the variable is declared. True is the default.

scope

(optional) The scope of the variable. Can be either AT_BEGIN, AT_END, or NESTED. Defaults to NESTED.

Variable Synchronization

The web container handles the synchronization of variables between a tag file and a calling page. Table 8–5 summarizes when and how each object is synchronized according to the object’s scope.

Table 8–5 Variable Synchronization Behavior

Tag File Location 

AT_BEGIN

NESTED

AT_END

Beginning 

Not sync. 

Save 

Not sync. 

Before any fragment invocation using jsp:invoke or jsp:doBody (see Evaluating Fragments Passed to Tag Files)

Tag->page 

Tag->page 

Not sync. 

End 

Tag->page 

Restore 

Tag->page 

If name-given is used to specify the variable name, then the name of the variable in the calling page and the name of the variable in the tag file are the same and are equal to the value of name-given.

The name-from-attribute and alias attributes of the variable directive can be used to customize the name of the variable in the calling page while another name is used in the tag file. When using these attributes, you set the name of the variable in the calling page from the value of name-from-attribute at the time the tag was called. The name of the corresponding variable in the tag file is the value of alias.

Synchronization Examples

The following examples illustrate how variable synchronization works between a tag file and its calling page. All the example JSP pages and tag files reference the JSTL core tag library with the prefix c. The JSP pages reference a tag file located in /WEB-INF/tags with the prefix my.

AT_BEGIN Scope

In this example, the AT_BEGIN scope is used to pass the value of the variable named x to the tag’s body and at the end of the tag invocation.

<%-- callingpage.jsp --%>
<c:set var="x" value="1"/>
${x} <%-- (x == 1) --%>
<my:example>
    ${x} <%-- (x == 2) --%>
</my:example>
${x} <%-- (x == 4) --%>
<%-- example.tag --%>
<%@ variable name-given="x" scope="AT_BEGIN" %>
${x} <%-- (x == null) --%>
<c:set var="x" value="2"/>
<jsp:doBody/>
${x} <%-- (x == 2) --%>
<c:set var="x" value="4"/>
NESTED Scope

In this example, the NESTED scope is used to make a variable named x available only to the tag’s body. The tag sets the variable to 2, and this value is passed to the calling page before the body is invoked. Because the scope is NESTED and because the calling page also had a variable named x, its original value, 1, is restored when the tag completes.

<%-- callingpage.jsp --%>
<c:set var="x" value="1"/>
${x} <%-- (x == 1) --%>
<my:example>
    ${x} <%-- (x == 2) --%>
</my:example>
${x} <%-- (x == 1) --%>
<%-- example.tag --%>
<%@ variable name-given="x" scope="NESTED" %>
${x} <%-- (x == null) --%>
<c:set var="x" value="2"/>
<jsp:doBody/>
${x} <%-- (x == 2) --%>
<c:set var="x" value="4"/>
AT_END Scope

In this example, the AT_END scope is used to return a value to the page. The body of the tag is not affected.

<%-- callingpage.jsp --%>
<c:set var="x" value="1"/>
${x} <%-- (x == 1) --%>
<my:example>
    ${x} <%-- (x == 1) --%>
</my:example>
${x} <%-- (x == 4) --%>
<%-- example.tag --%>
<%@ variable name-given="x" scope="AT_END" %>
${x} <%-- (x == null) --%>
<c:set var="x" value="2"/>
<jsp:doBody/>
${x} <%-- (x == 2) --%>
<c:set var="x" value="4"/>
AT_BEGIN and name-from-attribute

In this example the AT_BEGIN scope is used to pass an EL variable to the tag’s body and make to it available to the calling page at the end of the tag invocation. The name of the variable is specified by the value of the attribute var. The variable is referenced by a local name, result, in the tag file.

<%-- callingpage.jsp --%>
<c:set var="x" value="1"/>
${x} <%-- (x == 1) --%>
<my:example var="x">
    ${x} <%-- (x == 2) --%>
    ${result} <%-- (result == null) --%>
    <c:set var="result" value="invisible"/>
</my:example>
${x} <%-- (x == 4) --%>
${result} <%-- (result == ”invisible’) --%>
<%-- example.tag --%>
<%@ attribute name="var" required="true" rtexprvalue="false"%>
<%@ variable alias="result" name-from-attribute="var"
    scope="AT_BEGIN" %>
${x} <%-- (x == null) --%>
${result} <%-- (result == null) --%>
<c:set var="x" value="ignored"/>
<c:set var="result" value="2"/>
<jsp:doBody/>
${x} <%-- (x == ”ignored’) --%>
${result} <%-- (result == 2) --%>
<c:set var="result" value="4"/>