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 the following two value expressions:
${customer.name}
#{customer.name}
The former uses immediate evaluation syntax, whereas the latter uses deferred evaluation syntax. The first expression accesses the name property, gets its value, adds the value to the response, and gets rendered on the page. The same can happen with the second expression. However, the tag handler can defer the evaluation of this expression to a later time in the page lifecycle, if the technology using this tag allows.
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 request, this expression can be used to set the value of the name property with user input. In this case, the expression acts as an lvalue expression.
Both rvalue and lvalue expressions can refer to the following objects and their properties or attributes:
JavaBeans components
Collections
JavaTM SE enumerated types
Implicit objects
To refer to these objects, you write an expression using a variable which is the name of the object. The following expression references a backing bean (a JavaBeans component) called customer.
${customer}
The web container evaluates the variable that appears in an expression by looking up its value according to the behavior of PageContext.findAttribute(String), where the String argument is the name of the variable. For example, when evaluating the expression ${customer}, the container will look for customer in the page, request, session, and application scopes and will return its value. If customer is not found, null is returned.
You can alter the way variables are resolved with a custom EL resolver. For instance, you can provide an EL resolver that intercepts objects with the name customer, so that ${customer} returns a value in the EL resolver instead. Creation of custom EL resolvers is an advanced topic covered in Java EE 6 Tutorial, Volume II: Advanced Topics.
To reference an enum constant with an expression, use a String literal. For example, consider this Enum class:
public enum Suit {hearts, spades, diamonds, clubs}
To refer to the Suit constant, Suit.hearts with an expression, you use the String literal, "hearts". Depending on the context, the String literal is converted to the enum constant automatically. For example, in the following expression in which mySuit is an instance of Suit, "hearts" is first converted to Suit.hearts before it is compared to the instance.
${mySuit == "hearts"}
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 language. For more information on ECMAScript, see http://www.ecmascript.org.
If you want to reference the name property of the customer bean, use either the expression ${customer.name} or the expression ${customer["name"]}. The part inside the square brackets is a String 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:
${customer.address["street"]}
Properties of an enum can also be referenced in this way. However, as with JavaBeans component properties, the properties of an Enum class 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 which can be referenced by an expression.
For example, consider 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 the Planet Enum class:
${myPlanet.mass}
If you are accessing an item in an array or list, you must use either a literal value that can be converted 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 converted to int:
${customer.orders[1]}
${customer.orders.socks}
In contrast, an item in a Map can be accessed using a string literal key; no coercion is required:
${customer.orders["socks"]}
An rvalue expression also refers directly to values that are not objects, such as the result of arithmetic operations and literal values, as shown by these examples:
${"literal"}
${customer.age + 20}
${true}
${57}
The unified expression language defines the following literals:
Boolean: true and false
Integer: as in Java
Floating point: as in Java
String: with single and double quotes; " is escaped as \", ’ is escaped as \', and \ is escaped as \\
Null: null
You can also write expressions that perform operations on an enum constant. For example, consider the following Enum class:
public enum Suit {club, diamond, heart, spade }
After declaring an enum constant called mySuit, you can write the following expression to test if mySuit is spade:
${mySuit == "spade"}
When the EL resolving mechanism resolves this expression, it will invoke the valueOf method of the Enum class with the Suit class and the spade type, as shown here:
mySuit.valueOf(Suit.class, "spade"}
Value expressions using the ${} delimiters can be used in the following places:
In static text
In any standard or custom tag attribute that can accept an expression
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:
<some:tag> some text ${expr} some text </some:tag>
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.
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 converted 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 composite expressions. They are evaluated from left to right. Each expression embedded in the composite expression is converted to a String and then concatenated with any intervening text. The resulting String is then converted 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 converted 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 mean Suit.hearts. The literal is converted to Suit and the attribute gets the value Suit.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 type float will result in the following conversion:
Float.valueOf("1.2E4").floatValue()
See Section 1.18 of the JavaServer Pages 2.1 Expression Language Specification (available from http://jcp.org/aboutJava/communityprocess/final/jsr245/) for the complete type conversion rules.