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

 About This Book

 JSP (JavaServer Pages) Overview

 Tomcat 7 Installation on Windows Systems

 JSP Scripting Elements

 Java Servlet Introduction

 JSP Implicit Objects

 Syntax of JSP Pages and JSP Documents

 JSP Application Session

 Managing Cookies in JSP Pages

 JavaBean Objects and "useBean" Action Elements

 Managing HTTP Response Header Lines

 Non-ASCII Characters Support in JSP Pages

 Performance of JSP Pages

EL (Expression Language)

 What is EL (Expression Language)?

 EL Expression Types and Usage

 Literal Data and Named Variables

 Basic Operators and Operations

 Predefined Implicit Objects

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)

 JSTL Core Library

 JSP Custom Tags

 JSP Java Tag Interface

 Custom Tag Attributes

 Multiple Tags Working Together

 File Upload Test Application

 Outdated Tutorials

 References

 PDF Printing Version