Basics
JSP pages consist of elements and template content.
Elements are interpreted by the JSP container.
Template content is static.
Elements are of three types:
- directives - global info, independent of the request, used in translation
- actions - used during processing, can be standard or custom, XML element syntax ("tags")
- scripting elements - declarations, scriptlets and expressions (classic and EL)
Two phase processing:
- translation - builds the servlet class - one time only
- execution - runs the servlet - once per request
Two general syntaxes:
- classic style - .jsp
- XML style - .jspx
Scripting element syntax:
- declarations - <%! ... %>
- scriptlets - <% ... %>
- classic expressions - <%= ... %>
- EL expressions - ${...}
A JSP document is a JSP page that is also an XML document.
A JSP document cannot contain elements which use the <% ... %> syntax.
Comments:
- <!-- ... --> - passed to client
- <%-- ... --%> - removed during translation
Scopes:
| page | accessible from within the page where they are created | values stored in the 'pageContext' object | javax.servlet.jsp.PageContext |
| request | accessible from all pages processing the same request | values stored in the 'request' object | javax.servlet.http.HttpServletRequest |
| session | accessible for all pages processing all requests in the same session | values stored in the 'session' object | javax.servlet.http.HttpSession |
| application | accessible from all pages in the web application | values stored in the 'application' object | javax.servlet.ServletContext |
Implicit objects:
| pageContext | javax.servlet.jsp.PageContext | ||
| request | javax.servlet.http.HttpServletRequest | ||
| response | javax.servlet.http.HttpServletResponse | ||
| session | javax.servlet.http.HttpSession | ||
| application | javax.servlet.ServletContext | ||
| out | javax.servlet.jsp.JspWriter | ||
| config | javax.servlet.ServletConfig | ||
| page | java.lang.Object | The class implementing the page (i.e. 'this') | |
| exception | java.lang.Throwable | An uncaught exception |
Directives
Directives use the <%@ ... %> syntax.
The equivalent XML syntax is <jsp:directive.xxx ...>, where
xxx is one of the directive types.
There are three types:
| page | page-dependent properties |
| include | specifies an include file |
| taglib | specifies a taglib to import |
page
Attributes for the page directive
| language | the scripting language, only legal value is "java", and "java" is the default |
| extends | fully qualified name of the superclass |
| import | imports packages; by default, the following are imported: java.lang.*, javax.servlet.*, javax.servlet.jsp.*, javax.servlet.http.* |
| session | indicates whether the page participates in the session; if false, the 'session' variable cannot be used; default is true |
| buffer | buffing model; 'none' indicates no buffering requested; 'nnnkb' requests buffering with a buffer size of at least nnn |
| autoFlush | indicates whether the buffer should be flushed when filled (true), or throw exception when buffer fills (false); cannot set autoFlush=false when buffer=none; default is true |
| isThreadSafe | requests the servlet thread model; requests are serialized if false; this value is now deprecated |
| info | information, available from Servlet.getServletInfo() |
| errorPage | defines the error page to forward to in the case of uncaught exceptions |
| isErrorPage | indicates whether this page is the target of an errorPage elsewhere; if true, then the implicit 'exception' object can be used |
| contentType | the MIME type; default is text/html for classic JSP and text/xml for JSP documents |
| pageEncoding | defines the character encoding |
| isELIgnored | defines whether EL expressions should be ignored or processed |
Examples:
<%@ page language="java" buffer="none" errorPage="/error.html" import="net.alethis.util.*" %>
<jsp:directive.page buffer="none" errorPage="/error.html" import="net.alethis.util.*"/>
When the XML syntax is used, the directive must be a child of the root element.
taglib
Attributes for the taglib directive
| uri | the location of the tag library descriptor |
| tagdir | prefix for locating tag extensions in WEB-INF/tags; must start with /WEB-INF/tags/; not entirely clear to me; either tagdir or uri should be specified |
| prefix | the taglib element namespace prefix |
Examples:
<%@ taglib uri="http://www.alethis.net/tags/nugtags" prefix="nug" %>
<jsp:directive.taglib uri="http://www.alethis.net/tags/nugtags" prefix="nug"/>
When the XML syntax is used, the directive must be a child of the root element.
include
The include directive statically imports text at translation time.
The attributes are:
| file | the file to include |
Examples:
<%@ include file="/common/banner.html" %>
<jsp:directive.include file="/common/banner.html"/>
The <jsp:include page='...'/> action is used to dynamically
include other resources.
Unlike a static include, the included resource is processed dynamically
as a separate JPS page, and its output is included in the current
page's output stream.
Scripting elements
Declarations declare methods and variables used in a JSP page.
They do not contribute to the output stream.
<%! int k; %>
<%! public int twice(int k) {
return 2*k;
}
%>
<jsp:declaration>String s;</jsp:declaration>
<jsp:declaration>
public int thrice(int k) {
return 3*k;
}
</jsp:declaration>
Scriptlets consist of executable statements.
They are processed at page execution time.
They may contribute to the output stream.
<% if (i % 2 == 0) { %>
even
<% } else { %>
odd
<% } %>
<jsp:scriptlet> if (i % 2 == 0) { </jsp:scriptlet>
even
<jsp:scriptlet> } else { </jsp:scriptlet>
odd
<jsp:scriptlet> } </jsp:scriptlet>
Expressions are Java expressions which are evaluated at page
processing time, and then coerced to a String.
<%= (new java.util.Date()).toString() %>
<jsp:expression> (new java.util.Date()).toString() </jsp:expression>
If EL is not disactivated, either via the page attribute isELIgnored,
or via the web.xml file (via the <el-ignored> or <scripting-invalid> elements), then an EL expression
can be used in place of <%= ... %> or <jsp:expression>...</jsp:expression>.
The syntax is simply ${...}.
An EL expression can be used inside a tag as an attribute value or in the
body if the documentation states that it acceptes run-time expressions.
Generally, expressions can be used for request-time translation elements,
and not for page-time translation elements.
Most attributes have page-time translation semantics, but the following
are request-time, and expressions can be used for them:
- jsp:setProperty - value
- jsp:useBean - beanName
- jsp:include - page
- jsp:forward - page
- jsp:param - value
- jsp:plugin - width and height
- jsp:element - name
The Expression Language
EL expressions can be used:
- In any attribute that accepts a run-time expression
- In template text
The attribute value can be plain text, a single expression or a
combination of expressions and text.
<nug:zippy zonk="${expr}"/>
<nug:zippy zonk="plain old text"/>
<nug:zippy zonk="${expr1}-${expr2}-${expr3}"/>
Various implicit objects are available in any EL expression:
| pageContext | The PageContext object |
| pageScope | A map that associates page-scoped attribute names to values |
| requestScope | A map that associates request-scoped attribute names to values |
| sessionScope | A map that associates session-scoped attribute names to values |
| applicationScope | A map that associates application-scoped attribute names to values |
| param | A map that associates parameter names to their first values |
| paramValues | A map that associates parameter names to a String[] of values |
| header | A map that associates header names to their first values |
| headerValues | A map that associates header names to a String[] of values |
| cookie | A map that associates cookie names to Cookies |
| initParam | A map that associates init param names to values |
Examples:
${pageContext.request.requestURI}
${param.userName}
${sessionScope.userContainer.name}
The process for evaluating an expression ${x} is as follows:
- Check if x is one of the implicit objects described above; if so, return its value
- Search for an attribute named x in the page, request, session and application scopes; if found, return the value
- Otherwise, return null
In expressions, can use a[b] notation for accessing lists, maps and arrays.
Arithmetic operators: + - * div / % mod
Relational operators: == != < <= > >= eq ne le lt ge gt
Logical operators: && || ! and or not
Empty: ${empty a} - returns true if a is null, an empty string, array, map or collection
Scoped objects: ${a} - searches for a the page, request, session and application scopes
Tag library functions: ${nug:func(a, b, 3)} - nug identifies the tag library.
The corresponding methods in the tag library must be static, and are declared
in the tag library descriptor files.
<taglib>
...
<function>
<name>func</name>
<function-class>net.alethis.tags.NuggyBugs</function-class>
<function-signature>
java.lang.String functor(String a, String b, int c)
</function-signature>
</function>
...
</taglib>
JSP Configuration
Configuration is done through the <jsp-config> element in the web.xml file.
It has two subelements: <taglib> and <jsp-property-group>.
The taglib element defines the mapping from a taglib uri to the descriptor file:
<jsp-config>
<taglib>
<taglib-uri>/NugTags</taglib-uri>
<taglib-location>/WEB-INF/tlds/Nug.tld</taglib-location>
</taglib>
</jsp-config>
With this definition, it can be used as:
<%@ taglib uri='/NugTags' prefix='nug' %>
Alternatively, you can just refer directly to the tld, but this is less flexible.
<%@ taglib uri='/WEB-INF/tlds/Nug.tld' prefix='nug' %>
jsp-property-group elements are used to:
- Indicate that a resource is a JSP page
- Indicate that a resource is a JSP document
- Disable EL expressions
- Disable scripting expressions
- Specify page encodings
- Define prelude and code includes
Example:
<jsp-config>
<jsp-property-group>
<url-pattern>/*.jsp</url-pattern>
<el-ignored>false</el-ignored>
<scripting-invalid>true</scripting-invalid>
<is-xml>true</is-xml>
<include-prelude>/WEB-INF/jspf/includes.jspf</include-prelude>
<include-coda>/WEB-INF/jspf/coda.jspf</include-coda>
</jsp-property-group>
</jsp-config>
Standard Actions
jsp:useBean
Creates a scripting variable, and associates it with a bean.
Attributes:
| id | Identifies the bean in the scope, and also provides the name of the scripting variable. |
| scope | 'page', 'request', 'session' or 'application'; 'page' is the default |
| class | fully qualified name of the implementation class |
| beanName | [RTEXPR] package and class name of bean to instantiate |
| type | fully qualified name for the type of the scripting variable; can be the class, a superclass or an implemented interface; default if not specified is the class |
Basic idea is to look for an attribute whose name is given by the id attribute, in the
specified scope.
If not found, the bean can be created.
At least one of class and type must be present.
It is forbidden to supply both class and beanName.
If class and type are both present, class must be assignable to type.
The body of the useBean element can be used to initialize the bean value,
typically with <jsp:setProperty> elements.
Among class, beanName and type, the following combinations are permitted: class, type, class/type, beanName/type
<jsp:useBean id="company" class="net.alethis.corp.Company"/>
<jsp:useBean id="company" scope="session" class="net.alethis.corp.Company"/>
<jsp:useBean id="company" class="net.alethis.corp.Company" type="net.alethis.Entity"/>
jsp:setProperty
Sets a property on a bean.
Attributes:
| name | The name of the bean |
| property | The property on the bean to set. If the value is '*', the container will copy all correspondingly named non-empty request parameter to the bean. |
| value | [RTEXPR] The value to set |
| param | The name of the request parameter to copy to the bean. If not supplied, the name of the property will be used. If the parameter is non-existent, or empty, the bean remains unchanged. |
It is an error to specify both value and param.
<jsp:setProperty name="user" property="address" value="12 Maple St."/>
<jsp:setProperty name="user" property="*"/>
<jsp:setProperty name="user" property="name">
<jsp:setProperty name="user" property="firstName" param="firstname">
jsp:getProperty
Outputs a bean property.
Attributes:
| name | The name of the bean |
| property | The property to output |
<jsp:getProperty name="user" property="birthDate"/>
jsp:include
Includes the processing of a resource in the output stream.
Attributes:
| page | [RTEXPR] The page to include; interpreted relative to the current page. |
| flush | Flush before including the page? |
The body may contain <jsp:param> elements, which are passed
to the included page.
<jsp:include page="/images/logo.gif"/>
<jsp:include page="/editor.jsp">
<jsp:param name="object" value="cust107"/>
</jsp:include>
Note that the include directive is file-relative, while the include
action is page-relative. Hence the following:
A.jsp: <%@ include file="dir/B.jsp" @>
dir/B.jsp: <%@ include file="C.jsp" @>
-- The container will look for dir/C.jsp
A.jsp: <%@ include file="dir/B.jsp" @>
dir/B.jsp: <jsp:include page="C.jsp"/>
-- The container will look for C.jsp
-- because the current page is A.jsp
A.jsp: <jsp:include page="dir/B.jsp"/>
dir/B.jsp: <%@ include file="C.jsp" @>
-- The container will look for dir/C.jsp
A.jsp: <jsp:include page="dir/B.jsp"/>
dir/B.jsp: <jsp:include page="C.jsp"/>
-- The container will look for dir/C.jsp
jsp:forward
Executes a runtime dispatch to another resource in the same context.
The resource can be static or dynamic.
Attributes:
| page | [RTEXPR] The page to forward to. |
The body may contain <jsp:param> elements, which are passed
to the forwarded page.
<jsp:forward page="/error.html"/>
<jsp:forward page="/editor.jsp">
<jsp:param name="object" value="cust107"/>
</jsp:include>
jsp:param
Used in the body of an include or a forward.
Adds the specified parameter to the regular request parameters.
If a parameter of the same name already exists, then the new value
is added before it.
For example, if the request already has param1=value1, and
we add param1=value2 using <jsp:param>, then the result
will be param1=value2,value1.
Attributes:
| name | The parameter name. |
| value | [RTEXPR] The parameter value. |
<jsp:forward page="/editor.jsp">
<jsp:param name="object" value="${custid}"/>
</jsp:include>
jsp:plugin
Inserts an applet or some Bean conglomeration using the 'Java Plugin' component,
whatever the hell that is.
Corresponds to HTML OBJECT or EMBED.
Not of much use to me, so I'm skipping it.
jsp:attribute
Can be used to define an action attribute in the action's body rather than
in the start element, and also to specify attributes inside a <jsp:element> specifier.
The value of the attribute is specified in the body of the element.
Attributes:
| name | The name of the attribute. |
| trim | Should whitespace be trimmed from the start and end of the body at page translation time? |
<nug:important>
<jsp:attribute name="reason">reason23</jsp:attribute>
</nug:important>
<jsp:element name="person">
<jsp:attribute name="first-name">Bill</jsp:attribute>
<jsp:attribute name="last-name" trim="true">
Cook
</jsp:attribute>
</jsp:element>
jsp:body
Used to identify the body of an action; required when <jsp:attribute>
is being used for the same action.
There are no attributes.
<nug:important>
<jsp:attribute name="reason">reason23</jsp:attribute>
<jsp:body>This is the important text!</jsp:body>
</nug:important>
jsp:element
Outputs an XML element.
Useful when the element name is selected dynamically.
Attributes:
| name | [RTEXPR] The name of the element. |
<jsp:element name="${contentType}">
<jsp:attribute name="id">${id}</jsp:attribute>
<jsp:body>${content}</jsp:body>
</jsp:element>
jsp:invoke
Used for defining custom tags without programming. See later.
jsp:doBody
Used for defining custom tags without programming. See later.
jsp:text
Contributes its body to the output stream.
The body may include run-time expressions, but not actions.
No attributes.
<jsp:text> Some text by ${author} </jsp:text>
jsp:output
Used in JSP documents (i.e. XML) to influence the generated XML.
Attributes:
| omit-xml-declaration | Specifies whether or not to include the XML declaration (true, false). The default is true/false according as the JSP document has/doesn't have a <jsp:root> element. |
| doctype-root-element | Specifies the root element for a DOCTYPE declaration. |
| doctype-system | Specifies the system name for a DOCTYPE declaration. The DOCTYPE is output if this property is set. |
| doctype-public | Specifies the public name for a DOCTYPE declaration. This property may appear only if the doctype-system property is also specified. |
<?xml version='1.0' encoding='UTF-8'?>
<html xmlns:jsp='http://java.sun.com/JSP/Page'>
<jsp:output doctype-root-element='html'
doctype-public='-//W3C//DTD XHMTL Basic 1.0//EN'
doctype-system='http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd'/>
<body>
<h1>Example</h1>
</body>
</html>
produces:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHMTL Basic 1.0//EN'
'http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd'>
<html>
<body>
<h1>Example</h1>
</body>
</html>
jsp:root
Provides the root element for a JSP document.
Attributes:
| version | The JSP version number. |
The <jsp:root> element is also a convenient place to hang namespace declarations.
<jsp:root version='2.0'
xmlns:jsp='http://java.sun.com/JSP/Page'>
...
</jsp:root>
jsp:declaration
Declares variables or methods, in the XML syntax.
<jsp:declaration>int i;</jsp:declaration>
<jsp:declaration>
String cat(String s, String t) {
return s + '/' + t;
}
</jsp:declaration>
jsp:scriptlet
Executable code, in the XML syntax.
<jsp:scriptlet>if (x == 0) {</jsp:scriptlet>
There are no responses.
<jsp:scriptlet>}</jsp:scriptlet>
jsp:expression
Expressions, in the XML syntax.
<jsp:expression>(2 * width) + 10</jsp:expression>
JSP Documents
These are JSP pages written as namespace-aware XML documents.
The container needs to distinguish classic JSP pages and JSP documents, so that it
can apply XML well-formedness tests to the latter.
Identification of JSP documents can occur in three ways:
- via the <is-xml> element within a <jsp-property-group> element in web.xml
- via the .jspx extension
- the top element is <jsp:root>
Structure
May or may not have <jsp:root> as root element (this was mandatory in 1.2 but now relaxed).
Namespace used for all JSP artifacts.
Each taglib is in its own namespace. Taglib directives are not permitted.
XML can appear as template text, either with or without namespaces.
Use <jsp:text> to include template data verbatim. Can use CDATA inside.
Permitted elements:
- JSP directives and scripting elements in XML syntax
- EL expressions
- JSP standard actions
- jsp:root, jsp:text, jsp:output
- custom actions
- template data inside jsp:text elements
- template data consisting of XML fragments
Packaging
There are two choices for packaging:
- drop a .tag or .tagx into WEB-INF/tags or a subdirectory; no descriptor is needed
- places the tag files in META-INF/tags inside a jar file which in turn is placed in WEB-INF/lib; in this case, a descriptor is needed
Here's an example of packaging in a jar file.
The descriptor (alethis-util.tld) looks like:
<?xml version='1.0'?>
<taglib>
<description>Alethis utility tags</description>
<tlib-version>1.0</tlib-version>
<short-name>Alethis Util Tags</short-name>
<uri>http://www.alethis.net/tags/util</uri>
<tag-file>
<name>currDate</name>
<path>/META-INF/tags/currDate.tag</path>
</tag-file>
<tag-file>
<name>lookup</name>
<path>/META-INF/tags/lookup.tag</path>
</tag-file>
<tag-file>
<name>repeater</name>
<path>/META-INF/tags/repeater.tag</path>
</tag-file>
<tag-file>
<name>tabular</name>
<path>/META-INF/tags/tabular.tag</path>
</tag-file>
</taglib>
Then create the following directory structure:
META-INF
tags
currDate.tag
lookup.tag
repeater.tag
tabular.tag
alethis-util.tld
Jar it up, and drop it into WEB-INF/lib.
JSP pages need to use the specified uri (rather than tagdir) to access the tags:
<%@ taglib prefix="util" uri="http://www.alethis.net/tags/util" %>
It's entirely possible to reference tag files and classic tag handlers (using
the <tag> element in the same descriptor file.
Calling JSP pages cannot distinguish the tag implementation technique.
When tags are placed directly in WEB-INF/tags, each directory constitutes
a single tag library, and is accessed from JSP via the taglib directive
with the tagdir attribute.
A descriptor can optionally provide entries for tags in WEB-INF/tags, but
this is not necessary.
The JSP Container
When a JSP page is first invoked, the jspInit() method will be called.
The container compiles the JSP into a servlet, either immediately before, or
a long time before, and the servlet is initialized by a call to its init() method
upon first invocation. The init() method in turn calls jspInit().
Similarly, the jspDestroy() method is called when the servlet is destroyed,
from the servlet's destroy() method.
Calls to the JSP page are handled by the _jspService() method, but page authors
should not (in fact, cannot) override it!