JSP 2.1 introduced the Unified Expression Language.  This combined the EL syntax from the JSP and JSF specifications.  One of the features that this introduced for JSP tags is the concept of a deferred evaluation of expressions.  The syntax is slightly different when using a tag that is expecting a deferred expression.  A deferred expression is indicated by the '#' symbol and a run-time expression uses the '$' symbol.

<foo:deferred value="#{firstName}" />
<foo:runtime value="${firstName}" />

A page author can not just choose to use a deferred expression instead of a run-time one.  The tag that is being used has to define the attribute in the tag library differently.

<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<tag>
<!-- Runtime value attribute definition -->
<attribute>
<name>value</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
<!-- Deferred value attribute definition -->
<attribute>
<name>value</name>
<deferred-value>
<type>java.util.Date</type>
</deferred-value>
</attribute>
</tag>
</taglib>

Why would a tag use a deferred value?  JSP doesn't separate the evaluation of the page and the generation of the markup like JSF.  The deferred expression doesn't have the same obvious applications as in JSF.  I can think of a few situations where it is helpful.

  • The un-evaluated expression string is useful
  • The tag needs to modify the javax.el.ELContext (page scope variables, etc) before the expression is valid
  • The expression needs to be conditionally evaluated

Using the Expression String

I have used the expression string to generate the names of HTTP parameters.  This is useful when your application uses a web framework that binds parameters to a JavaBean.  A common tag is a page selector for a table with many rows that will not fit on a single page.  Here is an example that uses deferred expressions.

<tag:pager pageSize="#{pgSz}" firstResult="#{index}" />

The tag can access the string used to create the expression via the javax.el.ValueExpression.getExpressionString() method.  This allows the tag to emit anchor tags that contain the correct parameter name that specifies page size and first result values; http://.../search?pgSz=50&index=50.  If the expression string could not be inspected then the request parameters would need to be passed in as attributes or hard coded in the tag.  It is important to realize that this will only work if the expression is not a formula.  For instance: #{1 + pgSz}.  The expression string would not make a good parameter name.

Iteration without a Body

Iteration tags typically have an attribute that takes an iterable and then evaluate the tag body for each item in the iterable.  Simple iteration tags no longer need to have a body if the usage of the variable can be expressed in a couple deferred expressions.  An example of this is a tag that generates an HTML select element.

<tag:select name="color" options="${colors}" var="colorVar"
optionLabel="#{colorVar.label}" optionValue="#{colorVar.hex}" />

The optionLabel and optionValue attributes are using deferred expressions.  The evaluation of the expression depends on a page scope variable specified by the var attribute.  A deferred expression can be evaluated more than once.  This tag would iterate over the colors passed in, exposing the 'colorVar' variable each iteration and then evaluating the deferred expressions to generate the HTML option elements that are nested inside of the select element.

Conditional Evaluation

The tag is responsible for invoking the evaluation of a deferred expression.  This can be used when the evaluation modifies state or if the evaluation is known to be expensive.

<tag:table>
<tag:column header="#{msg['resource.key']}">
Column Data
</tag:column>
</tag:table>

The tags used above render an HTML table.  The header text is only needed for rendering the header row.  If the application uses a database to hold/override text keys then the expression might result in a database query if the key wasn't loaded or had been evicted from cache.  Using the deferred expression allows the tag to only evaluate the expression when the header text is needed; not for every invocation of the tag body as the table tag iterates over the items in the table.