Expression Language Support Tags - Functional Description

<expr>
<set>
<declare>


1. <expr>

The <expr> action evaluates an expression and outputs the result of the evaluation to the current JspWriter object. It is the equivalent of <%= %> with the difference that it is meant for the Expression Language world (as opposed to the scripting language world).

The expression to be evaluated is specified via the attribute value and must be in the syntax of the current Expression Language. The result of the evaluation is coerced to a String and is subsequently emitted into the current JspWriter object.

For example:

  Hello <c:expr value="$request:name"/>

is equivalent to

  Hello <%=pageContext.getAttribute("name", PageContext.SCOPE_REQUEST)%>

assuming the expression language interprets the elexprvalue $request:name as meaning the value of the name attribute in the request scope.

As a convenience, this action also supports the notion of default value for cases where the value of an object in the elexprvalue is not accessible. The default condition is triggered when the Expression Language throws an ExpressionException while evaluating the expression (to report failure to complete evaluation satisfactorily) or if the evaluation of the expression completes, but the result is null. This condition usually happens when one of the objects in the expression is null. For example, in the example below, this exception would be thrown if the address property of the customer object were null. Check the details of the expression language to clearly understand under which circumstances the ExpressionException is thrown.

The default value can be specified either via attribute default:

    <c:expr value="$customer.address.city" default="unknown"/>

or within the body of the tag:

    <c:expr value="$customer.address.city">
       <acme:defaultCity/>
    </c:expr>

The two ways to specify a default value cannot be used simultaneously.

The <expr> action  is only available in the EL version of the library.

2. <set>

The <set> action sets the value of an attribute in any of the JSP scopes (page, request, session, application). If the attribute does not already exist, it is created.

The JSP scoped attribute can be set either from attribute value:

  <c:set var="foo" scope="session" value="..."/>

or from the body of the tag:

  <c:set var="foo">
      ...
  </c:set>

Setting the value of a JSP scoped attribute from the tag's body content  is useful to solve the problem associated with the fact that a tag attribute's value cannot be set from a tag. In the past, a tag developer would have to offer extra "attributes as tags" so the value of these attributes could be set from other tags. For example:

  <acme:atag>
    <x:att1><x:foo>mumbojumbo</x:foo></x:att1>
  </acme:atag>

With the <set> tag, this can be handled without requiring the extra <att1> tag.

  <c:set var="att1"><x:foo>mumbojumbo</x:foo></c:set>
  <acme:atag att1="$att1"/>

Attribute scope is used to specify the scope of the JSP attribute targetted by the <set> tag. It is an optional attribute that defaults to "page". The accepted values are restricted to: page, request, session, and application.

The <set> tag is only available in the EL version of the library.

3. <declare>

Given that an Expression Language is supported in JSTL, the need for scripting should be reduced substantially. However, until a JSP.next comes around with native support for the Expression Language, page authors will still have to deal with situations where some attributes of non-JSTL tags must be specified as rtexprvalues.

For example, <myTag> below expects to receive an "Order" object using an rtexprvalue. Because var is not exported as a scripting variable in the <forEach> tag, the code below would trigger a translation time error because the scripting variable customer does not exist.

      <c:forEach items="$customers" var="customer">
        <acme:myTag order=<%=customer.getOrder()%> />
      </c:forEach>

There needs to be a simple way to define a scripting variable to bridge the gap between the EL and scripting worlds until JSP.next comes.

The <declare> tag is used for that purpose. In the example below, a scripting variable "customer" is created as a reference to the JSP scoped attribute of the same name.

      <c:forEach items="$customers" var="customer">
        <c:declare id="customer" type="acme.Customer"/>
        <acme:myTag order=<%=customer.getOrder()%> />
      </c:forEach>

When jsp.next comes, the above code would simply become:

      <c:forEach items="$customers" var="customer">
        <acme:myTag order="$customer.order" />
      </c:forEach>

without requiring any modification to the <acme:myTag> tag.

The same requirement for a bridge between the EL and scripting worlds exists whether a page author uses the EL or RT version of JSTL. This tag therefore exists in both the EL and RT versions of thelibrary.

The visibility of the scripting variable is always AT_END.