JSP Tutorials - Herong's Tutorial Examples - Version 4.03, by Dr. Herong Yang
Collection Elements and Object Properties
This section describes how Rvalue expressions with (.) and ([]) operations will be evaluated to access collection elements and object properties.
EL expression supports reference operations to collection elements and object properties by using "." and "[]" operators. But they are used in the way as ECMAScript, which is very different than Java. Here are the main steps of the evaluation process for Rvalue expressions:
0. Check syntax to only allow: "identifier_a.identifier_b" and "identifier_a[expression_b]".
1. Replacing "." operator by "[]" operator. So convert "identifier_a.identifier_b" to "identifier_a.['identifier_b']".
2. Evaluate the second operand. So convert "identifier_a[expresion_b]" to "identifier_a[value_b]".
3. If the first operand matches no existing object name, return null.
4. If the second operand evaluates to null, return null.
5. If the first operand reprents an array, try to finish the operation as "[]". So try to evaluate "identifier_a[value_b]" as is.
6. If the first operand reprents a map, try to finish the operation with a call to the get() method. So try to evaluate "identifier_a[value_b]" as "identifier_a.get(value_b)".
7. If the first operand represents an object of other types, try to finish the operation as a Java bean property accessing operation. So convert "identifier_a[value_b]" to "identifier_a[identifier_b]", then evaluate it as "identifier_a.get'Identifier_b'()".
8. If step 7 failed, try to finish the operation as an object member variable. So evaluate "identifier_a[identifier_b]" as "identifier_a.identifier_b". I am not so sure about this. Needs further research.
As you can see, this process is very complex. But it does make page author's life easier by putting a lot of intelligence behind this operation. But it also brings a lot of confusion when you debug the code.
The EL 2.1 specification about the "." and "[]" operators is quoted below as reference. But I believe my description is much easier to understand for Rvalue expressions.
expr-a.identifier-b is equivalent to expr-a["identifier-b"]; that is, the identifier identifier-b is used to construct a literal whose value is the identifier, and then the [] operator is used with that value. To evaluate expr-a[expr-b]: . Evaluate expr-a into value-a. . If value-a is null: . If expr-a[expr-b] is the last property being resolved: . If the expression is a value expression and ValueExpression.getValue(context) was called to initiate this expression evaluation, return null. . Otherwise, throw PropertyNotFoundException. [trying to de-reference null for an lvalue] . Otherwise, return null. . Evaluate expr-b into value-b . . If value-b is null: . If expr-a[expr-b] is the last property being resolved: . If the expression is a value expression and ValueExpression.getValue(context) was called to initiate this expression evaluation, return null. . Otherwise, throw PropertyNotFoundException. [trying to de-reference null for an lvalue] . Otherwise, return null. . If the expression is a value expression: . If expr-a[expr-b] is the last property being resolved: . If ValueExpression.getValue(context) was called to initiate this expression evaluation, invoke elResolver.getValue(context, value-a, value-b). . If ValueExpression.getType(context) was called, invoke elResolver.getType(context, value-a, value-b). . If ValueExpression.isReadOnly(context) was called, invoke elResolver.isReadOnly(context, value-a, value-b). . If ValueExpression.setValue(context, val) was called, invoke elResolver.setValue(context, value-a, value-b, val). . Otherwise: . Invoke elResolver.getValue(value-a, value-b). . Otherwise, the expression is a method expression: . If expr-a[expr-b] is the last property being resolved: . Coerce value-b to String. . Find the method on object value-a with name value-b and with the set of expected parameter types provided at parse time. If the method does not exist, or the return type does not match the expected return type provided at parse time, throw MethodNotFoundException. . If MethodExpression.invoke(context, params) was called, invoke the found method with the parameters passed to the invoke method. . If MethodExpression.getMethodInfo(context) was called, construct and return a new MethodInfo object. . Otherwise: . Invoke elResolver.getValue(value-a, value-b).
Last update: 2012.
Table of Contents
JSP (JavaServer Pages) Overview
Tomcat 7 Installation on Windows Systems
Syntax of JSP Pages and JSP Documents
JavaBean Objects and "useBean" Action Elements
Managing HTTP Response Header Lines
Non-ASCII Characters Support in JSP Pages
What is EL (Expression Language)?
Literal Data and Named Variables
Basic Operators and Operations
►Collection Elements and Object Properties
Expression Examples in Static Text
Expression Examples in Static Text - Result
EL Variables Are pageContext Attributes
Overview of JSTL (JSP Standard Tag Libraries)