SCWCD : Building JSP Pages Using the Expression Language (EL)
Given a scenario, write EL code that accesses the following implicit variables including:
pageScope, requestScope,
sessionScope, and applicationScope,
param and paramValues,
header and headerValues,
cookie, initParam and
pageContext.
There are several implicit objects that are available to EL expressions used in
JSP pages. These objects are always available under these names:
pageContext - the PageContext object.
Provides an API to access various objects including:
context - the context for the
JSP page's servlet and any Web components contained in
the same application.
session - the session object for the client.
request - the request triggering the
execution of the JSP page.
pageScope - a java.util.Map that maps
page-scoped attribute names to their values.
requestScope - a java.util.Map
that maps request-scoped attribute names to their values.
sessionScope - a java.util.Map
that maps session-scoped attribute names to their values.
applicationScope - a java.util.Map
that maps application-scoped attribute names to their values.
param - a java.util.Map that
maps parameter
names to a single String parameter value
(obtained by calling
ServletRequest.getParameter(String name)).
paramValues - a java.util.Map
that maps
parameter names to a String[] of all values for
that parameter (obtained by calling
ServletRequest.getParameterValues(String name)).
header - a java.util.Map that
maps header
names to a single String header value (obtained by calling
HttpServletRequest.getHeader(String name)).
headerValues - a java.util.Map
that maps
header names to a String[] of all values for that
header.
cookie - a java.util.Map that
maps cookie
names to a single Cookie object. Cookies are retrieved
according to the semantics of
HttpServletRequest.getCookies(). If the same name is
shared by multiple cookies, an implementation must use the FIRST one
encountered in the array of Cookie objects returned by the
getCookies() method. However, users of the
cookie implicit object must be aware that
the ordering of cookies is
currently unspecified in the servlet specification.
initParam - a java.util.Map
that maps
context initialization parameter names to their String
parameter value (obtained by calling
ServletContext.getInitParameter(String name)).
Examples:
The request's URI (obtained from HttpServletRequest):
${pageContext.request.requestURI}
The value of the numberOfItems property of the
session-scoped attribute named cart:
${sessionScope.cart.numberOfItems}
The context path:
${pageContext.request.contextPath}
The session-scoped attribute named 'profile'
(null if not found):
${sessionScope.profile}
The String value of the productId
parameter, or null if not found:
${param.productId}
The value of the productId request parameter:
${param["productId"]}
The String[] containing all values of the productId
parameter, or null if not found:
${paramValues.productId}
A collection's members can be accessed using square brackets as shown by
retrieval of the userName parameter from the
param object. Members of an array or List
can be accessed if the value in square brackets can be coerced to
an int.
<html>
<head><title>Customer Profile for ${param["userName"]}</title></head>
<body>
...
</body>
</html>
Maps can be accessed using the dot operator OR square brackets.
For example, ${param.userName} is
EQUIVALENT to ${param["userName"]}.
The host HTTP attribute:
${header["host"]}
Here is an example of accessing a page-scoped object that is called
pageColor:
<body bgcolor="${pageScope.pageColor}">
it is equivalent to:
<body bgcolor="${pageScope['pageColor']}">
Given a scenario, write EL code that uses the following operators: property access
(the '.' operator), collection access (the '[]' operator).
The EL borrows the JavaScript syntax for accessing structured data as either a
property of an object (with the '.' operator) or as a named array element
(with the ["name"] operator). JavaBeans component properties
and java.util.Map entries, using the key as the property
name, can be accessed this way. Here are some examples:
${myObj.myProperty}${myObj["myProperty"]}${myObj['myProperty']}${myObj[varWithThePropertyName]}
As shown here, an EL expression must always be enclosed within
'${' and '}' characters. The first three expressions access a property named
myProperty in an object represented by a variable named
myObj. The fourth expression access a property with a name
that's held by a variable. Instead of a single variable, this syntax can be used
with any expression that evaluates to the property name.
The ARRAY ACCESS operator is also used for data represented as a collection
of indexed elements, such as a Java array or a java.util.List:
${myList[2]}${myList[aVar + 1]}
Expressions with syntax '${identifier[subexpression]}'
are evaluated as follows:
Evaluate the identifier and the
subexpression; if either resolves to
null, the expression is null.
If the identifier is a BEAN:
The subexpression is
coerced to a String value and that string is
regarded as a name of one of the bean's properties. The
expression resolves to the value of
that property; for example, the expression
${name.["lastName"]} translates into the value
returned by name.getLastName().
If the identifier is an ARRAY:
The subexpression is
coerced to an int value and the expression
resolves to identifier[subexpression]. For example,
for an array named colors,
colors[3] represents the fourth object in the
array. Because the subexpression is coerced to an
int, you can also
access that color like this: colors["3"]; in that case,
JSTL coerces "3" into 3.
If the identifier is a LIST:
The subexpression is also coerced to an
int and the expression resolves to the value
returned from identifier.get(subexpression), for
example: colorList[3] and
colorList["3"] both resolve to the fourth element in
the list.
If the identifier is a MAP:
The subexpression is regarded as one of the map's keys.
That expression is not coerced to a value because map keys can be any
type of object. The expression evaluates to
identifier.get(subexpression), for example,
colorMap[Red] and colorMap["Red"].
The former expression is valid only if a scoped variable named
Red exists in one of the four JSP scopes and was
specified as a key for the map named colorMap.
Table 7.1. Summary of [] collection access operator | Identifier type | Example use | Method invoked |
|---|
| JavaBean |
${colorBean.red}
${colorBean["red"]}
${colorBean['red']}
| colorBean.getRed() | | Array |
${colorArray[2]}
${colorArray["2"]}
| Array.get(colorArray, 2) | | List |
${colorList[2]}
${colorList["2"]}
| colorList.get(2) | | Map |
${colorMap[red]}
| colorMap.get(pageContext.findAttribute("red")) |
${colorMap["red"]}
| colorMap.get("red") |
You access a map's values through its keys, which you can specify with the []
operator, for example, in table above, ${colorMap[red]} and
${colorMap["red"]}. The former specifies an IDENTIFIER for
the key, whereas the latter specifies a STRING. For the identifier, the
PageContext.findAttribute method searches all FOUR JSP
scopes (searching the page, request, session, and application scopes) for
a scoped variable with the name that you specify, in this case,
red. On the other hand, if you specify a string,
it's passed directly to the map's get method.
Given a scenario, write EL code that uses the following operators: aritmetic
operators, relational operators, and logical operators.
There are the arithmetic operators here: '+', '-', '*', '/', '%'. You can also use the
following for the '/' (division) and
'%' (remainder or modulo) operators: div
and mod.
You can see examples of these being used below:
6 + 7 = ${6+7}<br>
8 x 9 = ${8*9}<br>
The relational operators are shown below:
Table 7.2. The relational operators | Symbol version | Text Version |
|---|
| == | eq | | != | ne | | < | lt | | > | gt | | >= | ge | | <= | le |
Here are some basic comparisons:
Is 1 less than 2? ${1<2} <br>
Does 5 equal 5? ${5==5} <br>
Is 6 greater than 7? ${6 gt 7}<br>
The logical operators are the same as the Java Programming Language, but they
also have their textual equivalents within the EL.
Table 7.3. The logical operators | Symbol version | Text Version |
|---|
| && | and | | || | or | | ! | not |
The empty operator allows you to test the following:
Object references to see if they are null.
Strings to see if they are empty.
Arrays to see if they are empty.
Lists to see if they are empty.
Maps to see if they are empty.
You use the operator in the following way:
empty variableName
Given a scenario, write EL code that uses a function; write code for an EL
function; and configure the EL function in a tag library descriptor.
The EL has qualified functions, reusing the notion of qualification from XML
namespaces (and attributes), XSL functions, and JSP custom actions. Functions
are mapped to public static methods in
Java classes. In JSP 2.0 the map is
specified in the TLD. The full syntax:
ns:func(a1, a2, ..., an)
As with the rest of EL, this element can appear in attributes and directly in
template text.
The prefix ns must match the prefix of a tag library that
contains a function whose name and signature matches the function being invoked
(func), or a translation error must occur. If the prefix is
omitted, the tag library associated with the default namespace is used (this is only
possible in JSP documents).
In the following standard syntax example, func1 is associated with
some-taglib:
<%@ taglib prefix="some" uri="http://acme.com/some-taglib" %>
${some:func1(true)}
In the following JSP document example, both func2 and
func3 are associated with default-taglib:
<some:tag xmlns="http://acme.com/default-taglib"
xmlns:some="http://acme.com/some-taglib"
xmlns:jsp="http://java.sun.com/JSP/Page">
<some:other value="${func2(true)}">
${func3(true)}
</some:other>
</some:tag>
The Tag Library Descriptor (TLD) associated with a tag library lists the functions.
Each such function is given a name (as seen in the EL), and a static
method in
a specific class that will implement the function. The class specified in the TLD
must be a public class, and must be specified using
a fully-qualified class name
(INCLUDING PACKAGES). The specified method must be a public static
method in the
specified class, and must be specified using a fully-qualified return type followed
by the method name, followed by the fully-qualified argument types in
parenthesis, separated by COMMAS. Failure to satisfy these requirements shall result in
a translation-time error.
A tag library can have only one function element in the same tag library with
the same value for their name element. If two functions have the same name, a
translation-time error shall be generated.
The expression language allows you to define functions that can be invoked in an
expression. Functions must be programmed as a public
static method in a public class. Once the
function is developed, its signature is mapped in a Tag Library Descriptor (TLD).
Write class with STATIC function:
package com.example;
public class MyELFunctions {
public static String concat(String str1, String str2) {
return str1 + str2;
}
}
In order to use concat method we have to add a
function element to our tag library descriptor (TLD).
You'll have to create a TLD file if it doesn't already exist. A tag library descriptor
defines and configures tags in a tag library.
Here is /WEB-INF/example-taglib.tld:
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
web-jsptaglibrary_2_0.xsd" version="2.0">
<tlib-version>1.0</tlib-version>
<function>
<description>Concatenates two strings</description>
<name>concat</name>
<function-class>com.example.MyELFunctions</function-class>
<function-signature>
java.lang.String concat(java.lang.String, java.lang.String)
</function-signature>
</function>
</taglib>
Add a taglib element to the deployment descriptor (
/WEB-INF/web.xml):
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"
version="2.4">
<taglib>
<taglib-uri>http://www.server.com/example-taglib</taglib-uri>
<taglib-location>/WEB-INF/example-taglib.tld</taglib-location>
</taglib>
</web-app>
Notice the taglib-location specifies the location of the TLD.
The taglib-uri is, for the most part, an arbitrary name given to
the tag library. The name you give it can't conflict with other tag libraries in your
deployment descriptor. Adding the taglib element to
the deployment descriptor is actually
OPTIONAL. You could instead reference the TLD directly in the taglib
directive on JSP:
<%@ taglib prefix="my" uri="/WEB-INF/example-taglib.tld" %>
This is NOT recommended because it reduces flexibility if you ever choose to rename or
move the TLD. The uri would have to be changed in every JSP that used it.
The new JSP looks like the following:
<%@ taglib prefix="my" uri="http://www.server.com/example-taglib" %>
<html>
<head><title>EL Function example</title></head>
<body>
str1 is : ${param["str1"]} <br>
str2 is : ${param["str2"]} <br>
concatenated : ${my:concat(param["str1"], param["str2"])}
</body>
</html>
The prefix 'my' given in the taglib directive is
whatever you choose to distinguish it from tags and functions in other tag libraries used
in the JSP.
|