JSP Syntax and Semantics
JSP syntax is quite straightforward and compact: it all fits
on a double-page syntax card available from Sun at http://java.sun.com/products/jsp/syntax.pdf
(see also Appendix F). A JSP page
consists of template data and JSP elements. Template data is just HTML or XML;
the JSP processor passes it on to output untouched. JSP elements fall into the
following groups: directives,
scripting elements,
comments,
and actions.
Scripting elements are further subdivided into declarations, expressions
and code fragments,
or scriptlets.
The first three groups have always been part of JSP and they
have non-XML syntax, as well as alternative XML/Namespace syntax. The
"actions" group is more recent and has only XML/Namespace syntax.
Non-XML Syntax
Non-XML syntax of directives, scripting elements and
comments is summarized in the table below. You have seen all of them used in
our simple example
|
Type of Element
|
Syntax Description
|
Example
|
|
Directives
|
<%@ directive %>
|
<%@
page language="java" %>
|
|
|
|
|
|
Scripting
elements
|
|
|
|
Declarations
|
<%! declarations %>
|
<%!
int i=0, j=5; %>
|
|
Expressions
|
<%= expression %>
|
<%=
i+7 %>
|
|
Code fragments
|
<% code fragment %>
|
<%
if(i < j-4 { %>
|
|
|
|
|
|
Comments
|
<%-- comment --%>
|
<%--
not for the client --%>
|
Alternative XML Syntax
A JSP page that is also a valid XML document opens with the
following declarations:
<! DOCTYPE root
PUBLIC “-//Sun
Microsystems Inc.//DTD JavaServer Pages Version 1.0//EN”
"http://java.sun.com/products/jsp/dtd/jspcore_1_0.dtd">
<jsp:root xmlns:jsp="http://java.sun.com/products/jsp/dtd/jsp_1_0.dtd">
XML alternatives to older, non-XML syntax are summarized in
the following table:
|
Type of Element
|
Non-XML Syntax
|
XML Tag
|
|
Directives
|
<%@ directive %>
|
<jsp:directive.page ... />
<jsp:directive.include ... />
|
|
|
|
|
|
Scripting elements
|
|
|
|
Declarations
|
<%! declarations %>
|
<jsp:declaration>
...
</jsp:declaration>
|
|
Expressions
|
<%= expression %>
|
<jsp:expression>
...
</jsp:expression>
|
|
Code fragments
|
<% code fragment %>
|
<jsp:scriptlet>
...
</jsp:scriptlet>
|
|
|
|
|
|
Comments
|
<%-- comment --%>
|
<%-- not for the client --%>
|
Directives are empty elements that take a number of
attributes. Scripting elements have no attributes, and only PCDATA content. That content will often
contain special characters, such as <,
& and quotes. These have to be escaped,
or else the entire body of the scripting element has to be made into a CDATA section. The same consideration
applies to action elements, see below.
To us, writing extensive scripting elements seems like an
error-prone process in precisely the complex cases where it really matters. It
is possible that good "lint"-style tools will appear that will catch
a forgotten closing bracket. A better approach is never to write a scripting
element that is longer than a line or two, and use Java beans instead.
The taglib Directive
The one remaining JSP element, the taglib
directive, is not mentioned in the table because it does not translate into an
XML element, but rather results in a change of namespace. The purpose of the taglib directive is to introduce an
additional library of tags. That library is identified by a namespace uri and a namespace prefix, as in:
<%@ taglib
uri="http://www.mytaglibs.com/tags" prefix="private" %>
In the XML document corresponding to JSP pages, the taglib directive is represented as a
Namespace attribute (xmlns:name-of-tag-library).
The taglib directive
is not part of JSP 1.0 but JSP 1.1, so this whole little section may seem
premature. The reason we included it is because we believe that, once the
directive is implemented, it will become an extremely powerful tool for
creating mini-languages.
Semantics in Brief
Directives are addressed to the JSP engine. They do not
produce any output.
Within scripting elements, Declarations are exactly that, Java
declarations and, perhaps, initializations. Declarations do not produce any
output.
Expressions are Java expressions; they are evaluated and
their values are inserted into the output stream.
Code fragments are stretches of Java code. They don't have
to be complete statements or valid expressions.
JSP comments are not sent to the client; they are strictly
for documenting code.
You can also use standard XML comments in a JSP page and they
will be treated like regular XML comments. You can even include non-XML JSP
content in XML-style comments, and it will be treated as part of comments, i.e.
ignored.
The semantics of scripting elements are easy to understand;
it's just Java code. Directives and their attributes require a little more
discussion.
JSP Directives
There are three directives: page,
include and taglib.
However, taglib is not implemented in version
1.0, so we only use page and include.
Page Directive
The page directive has a number of attributes; the easiest
way to show them all is to quote the DTD definition of the jsp.directive.page element:
<!ELEMENT jsp:directive.page EMPTY>
<!ATTLIST jsp:directive.page
language CDATA
“java”
extends CDATA
#IMPLIED
contentType
CDATA “text/html; ISO-8859-1”
import CDATA
#IMPLIED
session
(true|false)“true”
buffer CDATA
“8kb”
autoFlush
(true|false)“true”
isThreadSafe(true|false)“true”
info CDATA
#IMPLIED
errorPage
CDATA #IMPLIED
isErrorPage(true|false)“false”
>
Let us go through them in order.
|
Directive
|
Description
|
|
language
|
Specify the language of
scripting elements; currently only Java is supported.
|
|
extends
|
Allows you to specify a parent
class for the servlet that is automatically generated from the JSP page. It
is rarely used because it prevents the engine from doing some optimizations.
|
|
contentType
|
Specifies the MIME type and
encoding; one per page.
|
|
import
|
Specifies Java packages and
classes to be imported.
|
|
session
|
If true, then the implicit variable
named session
of type javax.servlet.http.HttpSession
references the current/new session for the page; otherwise, that variable is
unavailable.
|
|
buffer
|
Controls the size of the
buffer associated with the JspWriter. If you want unbuffered output, set it to none.
|
|
autoFlush
|
Specifies whether the buffered
output should be flushed automatically (true value) when the buffer is
filled, or whether an exception should be raised (false value) to indicate buffer
overflow.
|
|
isThreadSafe
|
If false, the JSP page implementation
will implement javax.servlet.SingleThreadModel,
so that all requests sent to that instance will be delivered serially to the service()
method of the page implementation class. Synchronization issues are complex;
consult JSP 1.0 for a detailed discussion.
|
|
info
|
Provides an information
message about your JSP page; it becomes the return value of the Servlet.getServletInfo()
method of the implementation class.
|
|
errorPage
|
Specifies a relative URL of
the local page to which any Java programming language Throwable object(s) thrown but not
caught by the page implementation are forwarded to for error processing.
|
|
isErrorPage
|
Specifies whether this is or
is not an error page.
|
Here is an example of using page
from the Birthdays application (presented in full later in this chapter):
<%@ page import="java.util.*,
MyNa.utils.*" errorPage="errorpage.jsp" %>
Action Elements
Action elements fall into three groups as follows:
actions having to do with beans: useBean, getProperty, setProperty
include
and forward
actions, corresponding to the include() and forward() methods of the RequestDispatcher
interface in the javax.servlet
package (see Chapter 1)
the
plugin
action, for downloading a plug-in to the client (we don't use it in this book –
see the documentation for more details)
All action tags appear with the jsp:
namespace prefix. Some action elements are EMPTY, with a number of attributes; others
have content. When action elements appear in a JSP page that is intended to be
a well-formed and valid XML document, their content frequently has to be
wrapped in a CDATA section.
Beans and properties
Here is an example of using action elements from the
Birthdays application which we develop later in this chapter:
<jsp:useBean id="bbean"
scope="session" class="birthday.BirthdayBean" />
The id attribute of useBean specifies the name of the bean
within the application. The scope attribute can have one of the values we
discussed above: page, request, session,
or application. Finally, the class attribute
gives the fully-qualified class name of the bean. As the DTD says:
<!ELEMENT jsp:useBean %jsp.body;>
<!ATTLIST jsp:useBean
id ID #REQUIRED
class CDATA #REQUIRED
scope (page|session|request|application) “page”
>
You will notice from the first line that the DTD specifies useBean as having %jsp.body;
content. That content can be empty, as in our example, but it may not be. If
there is content, it is usually setProperty
elements that customize the bean. Alternatively, setProperty
elements may follow the useBean element.
Here is an example of using setProperty:
<jsp:setProperty name="bbean"
property="*" />
To set a property, one needs a property name and a value.
There are two sources for values. One is the attributes of a setProperty element:
<jsp:setProperty name="abean"
property="prop1" value="value1" />
More often, the values come from Request
parameters, ultimately, from form inputs on the client. In this case, instead
of value, you specify the name of the parameter whose value is to be used:
<jsp:setProperty name="abean"
property="prop1" param="param1" />
If the name of the bean property is the same as the name of
the request parameter, then you don't have to specify the parameter name. If
you want all request parameters copied to bean properties of the same name, you
code property="*", as in the
first example we looked at, above.
The Include Action
Here's an example that illustrates the include action. The action is performed only
if the condition in the preceding scriptlet holds true:
<% }else if("change".equals(select)){
%>
We have
changed <%= bbean.getNumberAffected() %> rows.
<%@
include file="continue.jsp" %>
<% }else if("msgsent".equals(select)){ %>
...
Two Include Mechanisms
Including material from other files is an important tool for
breaking up JSP pages into manageable components. There are two mechanisms for
inclusion, a directive and an action. Their properties are:
|
What
|
Syntax
|
Phase
|
Parsed?
|
|
directive
|
<%@
include file=... %>
|
translation-time
|
yes
|
|
action
|
<jsp:include
page=... />
|
request-time
|
no
|
We have found the include directive very useful in
structuring JSP applications, as you will see in the example later in this
chapter.
We hope you agree that, with the possible exception of
synchronization issues, the syntax and semantics of JSP pages are quite clear
and intuitive. (This does not mean that the current generation of JSP engines
always behave in clear and intuitive ways.) The main challenge, as we said in
the introduction, is in large-scale structuring of JSP applications. This is
what we are going to work on now. In the next section we present two possible
approaches, then illustrate one of them in a larger example application.