Unified Expression Language
The primary new feature of JSP 2.1 is the unified expression language (unified EL), which represents a union of the expression language offered by JSP 2.0 and the expression language created for JavaServer Faces technology (see Chapter 9) version 1.0.
The expression language introduced in JSP 2.0 allows page authors to use simple expressions to dynamically read data from JavaBeans components. For example, the test attribute of the following conditional tag is supplied with an EL expression that compares the number of items in the session-scoped bean named
cart
with 0.As explained in The Life Cycle of a JSP Page, JSP supports a simple request/response life cycle, during which a page is executed and the HTML markup is rendered immediately. Therefore, the simple, read-only expression language offered by JSP 2.0 was well suited to the needs of JSP applications.
JavaServer Faces technology, on the other hand, features a multi-phase life cycle designed to support its sophisticated UI component model, which allows for converting and validating component data, propagating component data to objects, and handling component events. To facilitate these functions, JavaServer Faces technology introduced its own expression language that included the following functionality:
See Using the Unified EL to Reference Backing Beans (page 298) for more information on how to use the unified EL in JavaServer Faces applications.
These two expression languages have been unified for a couple reasons. One reason is so that page authors can mix JSP content with JavaServer Faces tags without worrying about conflicts caused by the different life cycles these technologies support. Another reason is so that other JSP-based technologies could make use of the additional features similarly to the way JavaServer Faces technology uses them. In fact, although the standard JSP tags and static content continue to use only those features present in JSP 2.0, authors of JSP custom tags can create tags that take advantage of the new set of features in the unified expression language.
To summarize, the new, unified expression language allows page authors to use simple expressions to perform the following tasks:
The unified EL also allows custom tag developers to specify which of the following kinds of expressions that a custom tag attribute will accept:
- Immediate evaluation expressions or deferred evaluation expressions. An immediate evaluation expression is evaluated immediately by the JSP engine. A deferred evaluation expression can be evaluated later by the underlying technology using the expression language.
- Value expression or method expression. A value expression references data, whereas a method expression invokes a method.
- Rvalue expression or Lvalue expression. An rvalue expression can only read a value, whereas an lvalue expression can both read and write that value to an external object.
Finally, the unified EL also provides a pluggable API for resolving expressions so that application developers can implement their own resolvers that can handle expressions not already supported by the unified EL.
This section gives an overview of the unified expression language features by explaining the following topics:
Immediate and Deferred Evaluation Syntax
The unified EL supports both immediate and deferred evaluation of expressions. Immediate evaluation means that the JSP engine evaluates the expression and returns the result immediately when the page is first rendered. Deferred evaluation means that the technology using the expression language can employ its own machinery to evaluate the expression sometime later during the page's life cycle, whenever it is appropriate to do so.
Those expressions that are evaluated immediately use the ${} syntax, which was introduced with the JSP 2.0 expression language. Expressions whose evaluation is deferred use the
#{}
syntax, which was introduced by JavaServer Faces technology.Because of its multi-phase life cycle, JavaServer Faces technology uses deferred evaluation expressions. During the life cycle, component events are handled, data is validated, and other tasks are performed, all done in a particular order. Therefore, it must defer evaluation of expressions until the appropriate point in the life cycle.
Other technologies using the unified EL might have different reasons for using deferred expressions.
Immediate Evaluation
All expressions using the
${}
syntax are evaluated immediately. These expressions can only be used within template text or as the value of a JSP tag attribute that can accept runtime expressions.The following example shows a tag whose value attribute references an immediate evaluation expression that gets the total price from the session-scoped bean named cart:
The JSP engine evaluates the expression,
${sessionScope.cart.total}
, converts it, and passes the returned value to the tag handler.Immediate evaluation expressions are always read-only value expressions. The expression shown above can only get the total price from the cart bean; it cannot set the total price.
Deferred Evaluation
Deferred evaluation expressions take the form
#{expr}
and can be evaluated at other phases of a page life cycle as defined by whatever technology is using the expression. In the case of JavaServer Faces technology, its controller can evaluate the expression at different phases of the life cycle depending on how the expression is being used in the page.The following example shows a JavaServer Faces
inputText
tag, which represents a text field component into which a user enters a value. TheinputText
tag'svalue
attribute references a deferred evaluation expression that points to thename
property of thecustomer
bean.For an initial request of the page containing this tag, the JavaServer Faces implementation evaluates the
#{customer.name}
expression during the render response phase of the life cycle. During this phase, the expression merely accesses the value ofname
from thecustomer
bean, as is done in immediate evaluation.For a postback, the JavaServer Faces implementation evaluates the expression at different phases of the life cycle, during which the value is retrieved from the request, validated, and propagated to the
customer
bean.As shown in this example, deferred evaluation expressions can be value expressions that can be used to both read and write data. They can also be method expressions. Value expressions (both immediate and deferred) and method expressions are explained in the next section.
Value and Method Expressions
The unified EL defines two kinds of expressions: value expressions and method expressions. Value expressions can either yield a value or set a value. Method expressions reference methods that can be invoked and can return a value.
Value Expressions
Value expressions can be further categorized into rvalue and lvalue expressions. Rvalue expressions are those that can read data, but cannot write it. Lvalue expressions can both read and write data.
All expressions that are evaluated immediately use the
${}
delimiters and are always rvalue expressions. Expressions whose evaluation can be deferred use the#{}
delimiters and can act as both rvalue and lvalue expressions. Consider these two value expressions:The former uses immediate evaluation syntax, whereas the latter uses deferred evaluation syntax. The first expression accesses the
name
property, gets its value, and the value is added to the response and rendered on the page. The same thing can happen with the second expression. However, the tag handler can defer the evaluation of this expression to a later time in the page life cycle, if the technology using this tag allows it.In the case of JavaServer Faces technology, the latter tag's expression is evaluated immediately during an initial request for the page. In this case, this expression acts as an rvalue expression. During a postback, this expression can be used to set the value of the
name
property with user input. In this situation, the expression acts as an lvalue expression.Referencing Objects Using Value Expressions
Both rvalue and lvalue expressions can refer to the following objects and their properties or attributes:
See Implicit Objects for more detail on the implicit objects available with JSP technology.
To refer to these objects, you write an expression using a variable name with which you created the object. The following expression references a JavaBeans component called
customer
.The web container evaluates a variable that appears in an expression by looking up its value according to the behavior of
PageContext.findAttribute(String)
. For example, when evaluating the expression${customer}
, the container will look forcustomer
in the page, request, session, and application scopes and will return its value. Ifcustomer
is not found, null is returned. A variable that matches one of the implicit objects described in Implicit Objects will return that implicit object instead of the variable's value.You can alter the way variables are resolved with a custom EL resolver, which is a new feature of the unified EL. For instance, you can provide an ELResolver that intercepts objects with the name
customer
, so that${customer}
returns a value in the EL resolver instead. However, you cannot override implicit objects in this way. See EL Resolvers for more information on EL resolvers.You can set the variable name,
customer
when you declare the bean. See Creating and Using a JavaBeans Component for information on how to declare a JavaBeans component for use in your JSP pages.To declare beans in JavaServer Faces applications, you use the managed bean facility. See Backing Beans (page 295) for information on how to declare beans for use in JavaServer Faces applications.
When referencing an enum constant with an expression, you use a
String
literal. For example, consider this Enum class:To refer to the
Suit
constant,Suit.hearts
with an expression, you use theString
literal,"hearts"
. Depending on the context, theString
literal is converted to the enum constant automatically. For example, in the following expression in whichmySuit
is an instance ofSuit
,"hearts"
is first converted to aSuit.hearts
before it is compared to the instance.Referring to Object Properties Using Value Expressions
To refer to properties of a bean or an Enum instance, items of a collection, or attributes of an implicit object, you use the . or [] notation, which is similar to the notation used by ECMAScript.
So, if you wanted to reference the
name
property of thecustomer
bean, you could use either the expression${customer.name}
or the expression${customer["name"]}
. The part inside the square brackets is aString
literal that is the name of the property to reference.You can use double or single quotes for the
String
literal. You can also combine the [] and . notations, as shown here:Properties of an enum can also be referenced in this way. However, as with JavaBeans component properties, the Enum class's properties must follow JavaBeans component conventions. This means that a property must at least have an accessor method called
get<Property>
--where <Property>
is the name of the property-- so that an expression can reference it.For example, say you have an Enum class that encapsulates the names of the planets of our galaxy and includes a method to get the mass of a planet. You can use the following expression to reference the method
getMass
of thePlanet
Enum class:If you are accessing an item in an array or list, you must use either a literal value that can be coerced to int or the [] notation with an int and without quotes. The following examples could all resolve to the same item in a list or array, assuming that
socks
can be coerced toint
:In contrast, an item in a
Map
can be accessed using a string literal key; no coercion is required:An rvalue expression also refer directly to values that are not objects, such as the result of arithmetic operations and literal values, as shown by these examples:
The unified expression language defines the following literals:
You can also write expressions that perform operations on an enum constant. For example, consider the following Enum class:
After declaring an enum constant called
mySuit
, you can write the following expression to test ifmySuit
isspade
:When the EL resolving mechanism resolves this expression it will invoke the
valueOf
method of the Enum class with theSuit
class and thespade
type, as shown here:See JavaBeans Components for more information on using expressions to reference JavaBeans components and their properties.
Where Value Expressions Can Be Used
Value expressions using the
${}
delimiters can be used in the following places:The value of an expression in static text is computed and inserted into the current output. Here is an example of an expression embedded in static text:
If the static text appears in a tag body, note that an expression will not be evaluated if the body is declared to be
tagdependent
(see Tags with Attributes, page 199).Lvalue expressions can only be used in tag attributes that can accept lvalue expressions.
There are three ways to set a tag attribute value using either an rvalue or lvalue expression:
- With a single expression construct:
<some:tag value="${expr}"/>
<another:tag value="#{expr}"/>
These expressions are evaluated and the result is coerced to the attribute's expected type.
- With one or more expressions separated or surrounded by text:
<some:tag value="some${expr}${expr}text${expr}"/>
<another:tag value="some#{expr}#{expr}text#{expr}"/>
These kinds of expression are called a composite expressions. They are evaluated from left to right. Each expression embedded in the composite expression is coerced to a
String
and then concatenated with any intervening text. The resultingString
is then coerced to the attribute's expected type.- With text only:
<some:tag value="sometext"/>
This expression is called a literal expression In this case, the attribute's
String
value is coerced to the attribute's expected type. Literal value expressions have special syntax rules. See Literal Expressions for more information. When a tag attribute has an enum type, the expression that the attribute uses must be a literal expression. For example, the tag attribute can use the expression"hearts"
to meanSuit.hearts
. The literal is coerced toSuit
and the attribute gets the valueSuit.hearts
.All expressions used to set attribute values are evaluated in the context of an expected type. If the result of the expression evaluation does not match the expected type exactly, a type conversion will be performed. For example, the expression
${1.2E4}
provided as the value of an attribute of typefloat
will result in the following conversion:See section 1.17 of the Expression Language specification for the complete type conversion rules.
Method Expressions
Another feature of the unified expression language is its support of deferred method expressions. A method expression is used to invoke an arbitrary public method, which can return a result. A similar feature of the unified EL is functions. Method expressions differ from functions in many ways. Functions explains more about the differences between functions and method expressions.
Method expressions primarily benefit JavaServer Faces technology, but they are available to any technology that can support the unified expression language. Let's take a look at how JavaServer Faces technology employs method expressions.
In JavaServer Faces technology, a component tag represents a UI component on a page. The component tag uses method expressions to invoke methods that perform some processing for the component. These methods are necessary for handling events that the components generate and validating component data, as shown in this example:
<h:form> <h:inputText id="name" value="#{customer.name}" validator="#{customer.validateName}"/> <h:commandButton id="submit" action="#{customer.submit}" /> </h:form>The
inputText
tag displays aUIInput
component as a text field. Thevalidator
attribute of thisinputText
tag references a method, calledvalidateName
, in the bean, calledcustomer
. The TLD that defines theinputText
tag specifies what signature the method referred to by thevalidator
attribute must have. The same is true of thecustomer.submit
method referenced by theaction
attribute of thecommandButton
tag. The TLD specifies that thesubmit
method must return anObject
instance that specifies which page to navigate to next after the button represented by thecommandButton
tag is clicked.The
validation
method is invoked during the process validation phase of the life cycle, whereas thesubmit
method is invoked during the invoke application phase of the life cycle. Because a method can be invoked during different phases of the life cycle, method expressions must always use the deferred evaluation syntax.Similarly to lvalue expressions, method expressions can use the . and [] operators. For example,
#{object.method}
is equivalent to#{object["method"]}
. The literal inside the [] is coerced toString
and is used to find the name of the method that matches it. Once the method is found, it is invoked or information about the method is returned.Method expressions can be used only in tag attributes and only in the following ways:
- With a single expression construct, where
bean
refers to a JavaBeans component andmethod
refers to a method of the JavaBeans component:<some:tag value="#{bean.method}"/>
The expression is evaluated to a method expression, which is passed to the tag handler. The method represented by the method expression can then be invoked later.
- With text only:
<some:tag value="sometext"/>
Method expressions support literals primarily to support
action
attributes in JavaServer Faces technology. When the method referenced by this method expression is invoked, it returns theString
literal, which is then coerced to the expected return type, as defined in the tag's TLD.Defining a Tag Attribute Type
As explained in the previous section, all kinds of expressions can be used in tag attributes. Which kind of expression and how that expression is evaluated--whether immediately or deferred--is determined by the
type
attribute of the tag's definition in the TLD file that defines the tag.If you plan to create custom tags (see the chapter Custom Tags), you need to specify for each tag in the TLD what kind of expression it accepts. Table 4-2 shows the three different kinds of tag attributes that accept EL expressions, gives examples of expressions they accept and the type definitions of the attributes that must be added to the TLD. Note that it is illegal to use
#{}
syntax for a dynamic attribute or${}
syntax for a deferred attribute.
In addition to the tag attribute types shown in Table 4-2, you can also define an attribute to accept both dynamic and deferred expressions. In this case, the tag attribute definition contains both an
rtexprvalue
definition set totrue
and either adeferred-value
ordeferred-method
definition.Deactivating Expression Evaluation
Because the patterns that identify EL expressions--
${ }
and#{ }
--were not reserved in the JSP specifications before JSP 2.0, there might exist applications in which such patterns are intended to pass through verbatim. To prevent the patterns from being evaluated, you can deactivate EL evaluation in one of the following ways:
- Escape the #{ or ${characters as follows:
some text \#{ some more\${ text
and
<my:tag someAttribute="sometext\#{more\${text" />
- Configure your application with the
jsp-property-group
element to either allow the#{
characters as a String literal using thedeferred-syntax-allowed-as-literal
subelement or to treat all expressions as literals using theel-ignored
subelement:
<jsp-property-group>
<deferred-syntax-allowed-as-literal>
true
</deferred-syntax-allowed-as-literal>
</jsp-property-group>
or
<jsp-property-group>
<el-ignored>true</el-ignored>
</jsp-property-group>
- Configure the page with the
page
directive to either accept the#{
characters as String literals with thedeferredSyntaxAllowedAsLiteral
attribute or to ignore all EL expressions using theisELIgnored
attribute:
<%@page ... deferredSyntaxAllowedAsLiteral="true" %>
or
<%@ page isELIgnored ="true" %>
The valid values of these attributes are
true
andfalse
. IfisELIgnored
istrue
, EL expressions are ignored when they appear in static text or tag attributes. If it isfalse
, EL expressions are evaluated by the container only if the attribute hasrtexprvalue
set totrue
or the expression is a deferred expression.The default value of
isELIgnored
varies depending on the version of the web application deployment descriptor. The default mode for JSP pages delivered using a Servlet 2.3 or earlier descriptor is to ignore EL expressions; this provides backward compatibility. The default mode for JSP pages delivered with a Servlet 2.4 descriptor is to evaluate EL expressions; this automatically provides the default that most applications want.Literal Expressions
A literal expression evaluates to the text of the expression, which is of type String. It does not use the
${}
or#{}
delimiters.If you have a literal expression that includes the reserved
${}
or#{}
syntax, you need to escape these characters as follows.
- By creating a composite expression as shown here:
${'${'}exprA}
#{'#{'}exprB}
The resulting values would then be the strings
${exprA}
and
#{exprB}
.- The escape characters
\$
and\#
can be used to escape what would otherwise be treated as an eval-expression:
\${exprA}
\#{exprB}
The resulting values would again be the strings ${exprA} and #{exprB}.
When a literal expression is evaluated, it can be converted to another type. Table 4-3 shows examples of various literal expressions and their expected types and resulting values.
Table 4-3 Literal Expressions Expression Expected Type Result Hi String Hi true Boolean Boolean.TRUE 42 int 42
Literal expressions can be evaluated immediately or deferred and can be either value or method expressions. At what point a literal expression is evaluated depends on where it is being used. If the tag attribute that uses the literal expression is defined as accepting a deferred value expression then the literal expression references a value and is evaluated at a point in the life cycle that is determined by where the expression is being used and to what it is referring.
In the case of a method expression, the method that is referenced is invoked and returns the specified
String
literal. ThecommandButton
tag of the Guess Number application uses a literal method expression as a logical outcome to tell the JavaServer Faces navigation system which page to display next. See Navigation Model (page 292) for more information on this example.Resolving Expressions
The unified EL introduces a new, pluggable API for resolving expressions. The main pieces of this API are:
- The
ValueExpression
class, which defines a value expression- The
MethodExpression
class, which defines a method expression- An
ELResolver
class that defines a mechanism for resolving expressions- A set of
ELResolver
implementations, in which each implementation is responsible for resolving expressions that reference a particular type of object or property- An
ELContext
object that saves state relating to EL resolution, holds references to EL resolvers, and contains context objects (such asJspContext
) needed by the underlying technology to resolve expressions.Most application developers will not need to use these classes directly unless they plan to write their own custom EL resolvers. Those writing JavaServer Faces custom components will definitely need to use
ValueExpression
andMethodExpression
. This section details how expressions are resolved for the benefit of these developers. It does not explain how to create a custom resolver. For more information on creating custom resolvers, see the article, The Unified Expression Language. You can also refer to Request Processing (page 1167), which explains how the Duke's Bank application uses a custom resolver.Process of Expression Evaluation
When a value expression that is included in a page is parsed during an initial request for the page, a
ValueExpression
object is created to represent the expression. Then, theValueExpression
object'sgetValue
method is invoked. This method will in turn invoke thegetValue
method of the appropriate resolver. A similar process occurs during a postback whensetValue
is called if the expression is an lvalue expression.In the case of a method expression, a
BeanELResolver
is used to find the object that implements the method to be invoked or queried. Similarly to the process for evaluating value expressions, when a method expression is encountered, aMethodExpression
object is created. Subsequently, either theinvoke
orgetMethodInfo
method of theMethodExpression
object is called. This method in turn invokes theBeanELResolver
object'sgetValue
method. ThegetMethodInfo
is mostly for use by tools.After a resolver completes resolution of an expression, it sets the
propertyResolved
flag of theELContext
totrue
so that no more resolvers are consulted.EL Resolvers
At the center of the EL machinery is the extensible
ELResolver
class. A class that implementsELResolver
defines how to resolve expressions referring to a particular type of object or property. In terms of the following expression, aBeanELResolver
instance is called the first time to find the base object,employee
, which is a JavaBeans component. Once the resolver finds the object, it is called again to resolve the property,lName
of the employee object.The unified EL includes a set of standard resolver implementations. Table 4-4 lists these standard resolvers and includes example expressions that they can resolve.
Depending on the technology using the unified EL, other resolvers might be available. In addition, application developers can add their own implementations of
ELResolver
to support resolution of expressions not already supported by the unified EL by registering them with an application.All of the standard and custom resolvers available to a particular application are collected in a chain in a particular order. This chain of resolvers is represented by a
CompositeELResolver
instance. When an expression is encountered, theCompositeELResolver
instance iterates over the list of resolvers and consults each resolver it finds one that can handle the expression.If an application is using JSP technology, the chain of resolvers includes the
ImplicitObjectELResolver
and theScopedAttributeELResolver
. These are described in the following section.See section JSP2.9 of the JavaServer Pages 2.1 specification to find out the order in which resolvers are chained together in a
CompositeELResolver
instance.To learn how to create a custom EL resolver, see the article, The Unified Expression Language.
Implicit Objects
The JSP expression language defines a set of implicit objects:
pageContext
: The context for the JSP page. Provides access to various objects including:
servletContext
: The context for the JSP page's servlet and any web components contained in the same application. See Accessing the Web Context (page 85).session
: The session object for the client. See Maintaining Client State (page 86).request
: The request triggering the execution of the JSP page. See Getting Information from Requests (page 70).response
: The response returned by the JSP page. See Constructing Responses (page 72).In addition, several implicit objects are available that allow easy access to the following objects:
param
: Maps a request parameter name to a single valueparamValues
: Maps a request parameter name to an array of valuesheader
: Maps a request header name to a single valueheaderValues
: Maps a request header name to an array of valuescookie
: Maps a cookie name to a single cookieinitParam
: Maps a context initialization parameter name to a single valueFinally, there are objects that allow access to the various scoped variables described in Using Scope Objects (page 64).
JSP 2.1 provides two EL resolvers to handle expressions that reference these objects:
ImplicitObjectELResolver
andScopedAttributeELResolver
A variable that matches one of the implicit objects is evaluated by
ImplicitObjectResolver
, which returns the implicit object. This resolver only handles expressions with a base ofnull
. What this means for the following expression is that theImplicitObjectResolver
resolves thesessionScope
implicit object only. Once the implicit object is found, theMapELResolver
instance resolves theprofile
attribute because theprofile
object represents a map.
ScopedAttributeELResolver
evaluates a single object that is stored in scope. LikeImplicitObjectELResolver
, it also only evaluates expressions with a base ofnull
. This resolver essentially looks for an object in all of the scopes until it finds it, according to the behavior ofPageContext.findAttribute(String)
. For example, when evaluating the expression${product}
, the resolver will look forproduct
in the page, request, session, and application scopes and will return its value. Ifproduct
is not found,null
is returned.When an expression references one of the implicit objects by name, the appropriate object is returned instead of the corresponding attribute. For example,
${pageContext}
returns thePageContext
object, even if there is an existingpageContext
attribute containing some other value.Operators
In addition to the
.
and[]
operators discussed in Value and Method Expressions, the JSP expression language provides the following operators, which can be used in rvalue expressions only:
- Arithmetic:
+
,-
(binary),*
,/
anddiv
,%
andmod
,-
(unary)- Logical:
and
,&&
,or
,||
,not
,!
- Relational:
==
,eq
,!=
,ne
,<
,lt
,>
,gt
,<=
,ge
,>=
,le
. Comparisons can be made against other values, or against boolean, string, integer, or floating point literals.- Empty: The
empty
operator is a prefix operation that can be used to determine whether a value isnull
or empty.- Conditional:
A ? B : C
. EvaluateB
orC
, depending on the result of the evaluation ofA
.The precedence of operators highest to lowest, left to right is as follows:
Reserved Words
The following words are reserved for the JSP expression language and should not be used as identifiers.
Note that many of these words are not in the language now, but they may be in the future, so you should avoid using them.
Examples
Table 4-5 contains example EL expressions and the result of evaluating them.
Functions
The JSP expression language allows you to define a function that can be invoked in an expression. Functions are defined using the same mechanisms as custom tags (See Using Custom Tags and Chapter 7).
At first glance, functions seem similar to method expressions, but they are different in the following ways:
- Functions refer to static methods that return a value. Method expressions refer to non-static, arbitrary public methods on objects.
- Functions are identified statically at translation time, whereas methods are identified dynamically at runtime.
- Function parameters and invocations are specified as part of an EL expression. A method expression only identifies a particular method. The invocation of that method is not specified by the EL expression; rather, it is specified in the tag attribute definition of the attribute using the method expression, as described in Defining a Tag Attribute Type.
Using Functions
Functions can appear in static text and tag attribute values.
To use a function in a JSP page, you use a
taglib
directive to import the tag library containing the function. Then you preface the function invocation with the prefix declared in the directive.For example, the date example page
index.jsp
imports the/functions
library and invokes the functionequals
in an expression:<%@ taglib prefix="f" uri="/functions"%> ... <c:when test="${f:equals(selectedLocaleString, localeString)}" >In this example, the expression referencing the function is using immediate evaluation syntax. A page author can also use deferred evaluation syntax to reference a function in an expression, assuming that the attribute that is referencing the function can accept deferred expressions.
If an attribute references a function with a deferred expression then the function is not invoked immediately; rather, it is invoked whenever the underlying technology using the function determines it should be invoked.
Defining Functions
To define a function you program it as a public static method in a public class. The
mypkg.MyLocales
class in thedate
example defines a function that tests the equality of twoString
s as follows:package mypkg; public class MyLocales { ... public static boolean equals( String l1, String l2 ) { return l1.equals(l2); } }Then you map the function name as used in the EL expression to the defining class and function signature in a TLD. The following
functions.tld
file in the date example maps theequals
function to the class containing the implementation of the functionequals
and the signature of the function:<function> <name>equals</name> <function-class>mypkg.MyLocales</function-class> <function-signature>boolean equals( java.lang.String, java.lang.String )</function-signature> </function>No two functions within a tag library can have the same name.