The SPEL is designed to be the simplest possible JSPSTL expression language that is still useful. The only required features of the SPEL are:
The idea is to design a language that will eventually grow, keeping in mind that future versions of the language should be backwards compatible with this version of the SPEL.
The syntax is extremely simple. Attributes are accessed by name, with an optional scope ("page:", "request:", "session:", "app:"). Properties of attributes are accessed using the "." operator, and may be nested arbitrarily. Attribute and property names must be java identifiers, unless they are quoted. Relational comparisons are allowed using the relational operators (==, !=, <, >, <=, >=). Comparisons may be made against other values, or against boolean, String, integer, or floating point literals.
The following are the constructs supported by the SPEL:
Expression | ::= | Value |
| RelationalExpression | ||
RelationalExpression | ::= | Value RelOp Value |
RelOp | ::= | '==' |
| '!=' | ||
| '<' | ||
| '>' | ||
| '<=' | ||
| '>=' | ||
Value | ::= | PropertyValue |
| Literal | ||
PropertyValue | ::= | NamedValue |
| PropertyValue '.' Identifier | ||
| PropertyValue '.' StringLiteral | ||
NamedValue | ::= | ScopedIdentifier |
| Identifier | ||
ScopedIdentifier | ::= | ScopeName ':' Identifier |
| ScopeName ':' StringLiteral | ||
| ':' (Identifier | StringLiteral) | ||
ScopeName | ::= | 'page' |
| 'request' | ||
| 'session' | ||
| 'app' | ||
| 'header' | ||
| 'param' | ||
| 'paramvalues' | ||
Identifier | ::= | Java language identifier |
Literal | ::= | BooleanLiteral |
| IntegerLiteral | ||
| FloatingPointLiteral | ||
| StringLiteral | ||
| NullLiteral | ||
BooleanLiteral | ::= | 'true' |
| 'false' | ||
StringLiteral | ::= | '([^'\]|\'|\\)*' |
| "([^'\]|\'|\\)*" | ||
i.e., a string of any characters enclosed by single or double quotes, where \ is used to escape ', ", and \. | ||
IntegerLiteral | ::= | ["+","-"] ["1"-"9"] (["0"-"9"])* |
FloatingPointLiteral | ::= | (["+","-"])? (["0"-"9"])+ "." (["0"-"9"])* (["e","E"] (["+","-"])? (["0"-"9"])+)? |
| (["+","-"])? "." (["0"-"9"])+ (["e","E"] (["+","-"])? (["0"-"9"])+)? | ||
| (["+","-"])? (["0"-"9"])+ ["e","E"] (["+","-"])? (["0"-"9"])+ | ||
NullLiteral | ::= | 'null' |
Notes:
The following words are reserved for the language and should not be used as identifiers without being quoted.
and or not |
eq ne lt |
gt le ge |
true false null |
instanceof |
Note that these words may not be in the language now, but they may be in the future, so developers should avoid using these words now.
If a named value is specified with a scope of "page", "request", "session", or "app", its value is the value of that name in the given scope. If no scope is given, the value is found according to the rules of PageContext.findAttribute(name).
If a named value is specified with a scope of "header", its value is obtained by calling HttpServletRequest.getHeader(String).
If a named value is specified with a scope of "param", its value is obtained by calling ServletRequest.getParameter(String).
If a named value is specified with a scope of "paramvalues", its value is obtained by calling ServletRequest.getParameterValues(String).
In any of these cases, if a value is not found, the result is an ExpressionException, not "null".
The expression "value . propertyName" denotes a property expression. The property is found through introspection by treating the value as a JavaBean and calling the appropriate setter method. If the result is a primitive value, the result is converted to the Object equivalent of the primitive.
Note that these error conditions might be relaxed in the future, but for now they are as strict as possible.
In the future, the "." operator might be extended to interpret other name/value collections, such as Maps, but for now this is not the case. Note that in the future, the "Map behavior" might happen automatically, so JavaBeans should avoid implementing "java.util.Map" to avoid having their behavior change in the future.
Every expression is evaluated in the context of an "expected type". The result of the expression evaluation may not match the expected type exactly, so the following rules are applied:
The following rules are applied to evaluate a relational comparison.
The rules for equality are as follows:
The rules for ordered comparisons are as follows:
The ExpressionException mechanism in the JSTL is provided as a way for expression languages to indicate that there was a problem evaluating an expression, but the problem was small enough that a default value could be substituted in its place without invoking the entire JSP error handling mechanism.
The SPEL throws javax.servlet.jsp.jstl.core.ExpressionException in the following situations:
The SPEL is responsible for handling both expressions and literals. Expressions begin with a "$" character. For example:
<mytags:if test="$bean1.a < 3" />
Any value that does not begin with "$" is treated as a literal that is parsed to the expected type using the PropertyEditor for the expected type:
<mytags:if test="true" />
There may be literal values that start with the "$" character. If that is the case, the value must be escaped using the "\" character.:
<mytags:price price="\$3.95" />
If a value starts with "\$", it is treated as a literal value with the leading "\" removed.