1.1 What is
JSP?
JavaServer Pages (JSP) technology enables you to mix HTML content with dynamically generated content from servlets. A JSP page has a .jsp extension and resides (on most servers) anywhere an HTML file could go. The contents of a JSP page looks more like an HTML page than a Java source file. In fact, any valid HTML file, when given a .jsp extension, is also a valid JSP page. However, the power of a JSP page resides in the fact that you can use the power of special JSP tags to create dynamic content. Although what you write often looks more like HTML than a servlet, behind the scenes the JSP page is automatically converted into a servlet.
1.2 Advantages of JSP
JSP provides many advantages over alternative technologies such as Active Server Pages (ASP), ColdFusion, PHP, and servlets.
ASP is a Microsoft technology that locks one into Windows. JSP doesn't lock one into a particular operating system.
ColdFusion is a proprietary Macromedia technology that forces one to learn a new scripting language and ties one to a given server product that supports it. JSP doesn't force one to learn an entirely new, less widely used language. Also, JSP is an open standard that doesn't lock one into a particular server product.
PHP involves learning a new, less widely used language. JSP has the power of Java behind it, a familiar language with a rich API. Also, JSP is much more widely supported by server vendors than is PHP.
Servlets are very powerful, widely supported, and have the Java language behind them. However, when building an application using the MVC architecture, it is ideal to have control logic separated from the view. When servlets are used to generate HTML, the view and control logic are not cleanly separated. JSP technology can be used to take the presentation code out of the servlet. This allows a servlet to focus exclusively on control logic, leaving the presentation to the JSP page. Also, Web page design experts can build the HTML using familiar tools and then servlet programmers can easily insert the dynamic portion of the content later. It is often more convenient to write regular HTML than to have a bunch of println() statements that generate the HTML.
1.3 Disadvantages of JSP
The main disadvantage of JSP technology is that in a MVC framework, JSP pages do not force a strict separation of presentation from control logic. Scriptlets allow Java code to be embedded within a JSP page, allowing one to combine control and even model logic within a JSP page. It is up to the software architect to ensure that JSP pages provide only the presentation for an application, and that servlets (not JSP pages) are used for the control logic.
One alternative to JSP pages that solves this problem is Velocity. Velocity is a Java-based template engine that uses a template language to reference objects defined in Java code. This removes Java code from appearing within a presentation page.
Another way to cleanly separate an application's presentation from its control logic is to use the Apache Struts Web application framework. The Struts framework consists of a single servlet controller, customizeable action classes, and a custom tag library that allows all Java code to be removed from the JavaServer Pages. Struts also allows for easy mapping of HTML forms to JavaBeans.
2. SCRIPTING ELEMENTS
Scripting elements let you insert code into the servlet that will be generated from the JSP page. There are three forms:
1. Expressions of the form which are evaluated and inserted into the servlet's output.
2. Scriptlets of the form which are inserted into the servlet's appropriate service method (doGet(), doPost(), etc.).
3. Declarations of the form which are inserted into the body of the servlet class, outside of any existing methods.
2.1 Expressions
When the page is requested, the expression is evaluated, converted to a string, and inserted into the output of the servlet's appropriate service method (doGet(), doPost(), etc.).
ex:
Here is the time:
2.2 Scriptlets
When the page is requested, the code is executed in the appropriate service method (doGet(), doPost(), etc.)
ex:
This is the same as
The color is:
2.2.1 Making parts of the JSP file conditional
Heads
Tails
2.2.2 Predefined Variables in Expressions and Scriptlets
JavaServer Pages (JSP) technology enables you to mix HTML content with dynamically generated content from servlets. A JSP page has a .jsp extension and resides (on most servers) anywhere an HTML file could go. The contents of a JSP page looks more like an HTML page than a Java source file. In fact, any valid HTML file, when given a .jsp extension, is also a valid JSP page. However, the power of a JSP page resides in the fact that you can use the power of special JSP tags to create dynamic content. Although what you write often looks more like HTML than a servlet, behind the scenes the JSP page is automatically converted into a servlet.
1.2 Advantages of JSP
JSP provides many advantages over alternative technologies such as Active Server Pages (ASP), ColdFusion, PHP, and servlets.
ASP is a Microsoft technology that locks one into Windows. JSP doesn't lock one into a particular operating system.
ColdFusion is a proprietary Macromedia technology that forces one to learn a new scripting language and ties one to a given server product that supports it. JSP doesn't force one to learn an entirely new, less widely used language. Also, JSP is an open standard that doesn't lock one into a particular server product.
PHP involves learning a new, less widely used language. JSP has the power of Java behind it, a familiar language with a rich API. Also, JSP is much more widely supported by server vendors than is PHP.
Servlets are very powerful, widely supported, and have the Java language behind them. However, when building an application using the MVC architecture, it is ideal to have control logic separated from the view. When servlets are used to generate HTML, the view and control logic are not cleanly separated. JSP technology can be used to take the presentation code out of the servlet. This allows a servlet to focus exclusively on control logic, leaving the presentation to the JSP page. Also, Web page design experts can build the HTML using familiar tools and then servlet programmers can easily insert the dynamic portion of the content later. It is often more convenient to write regular HTML than to have a bunch of println() statements that generate the HTML.
1.3 Disadvantages of JSP
The main disadvantage of JSP technology is that in a MVC framework, JSP pages do not force a strict separation of presentation from control logic. Scriptlets allow Java code to be embedded within a JSP page, allowing one to combine control and even model logic within a JSP page. It is up to the software architect to ensure that JSP pages provide only the presentation for an application, and that servlets (not JSP pages) are used for the control logic.
One alternative to JSP pages that solves this problem is Velocity. Velocity is a Java-based template engine that uses a template language to reference objects defined in Java code. This removes Java code from appearing within a presentation page.
Another way to cleanly separate an application's presentation from its control logic is to use the Apache Struts Web application framework. The Struts framework consists of a single servlet controller, customizeable action classes, and a custom tag library that allows all Java code to be removed from the JavaServer Pages. Struts also allows for easy mapping of HTML forms to JavaBeans.
2. SCRIPTING ELEMENTS
Scripting elements let you insert code into the servlet that will be generated from the JSP page. There are three forms:
1. Expressions of the form which are evaluated and inserted into the servlet's output.
2. Scriptlets of the form which are inserted into the servlet's appropriate service method (doGet(), doPost(), etc.).
3. Declarations of the form which are inserted into the body of the servlet class, outside of any existing methods.
2.1 Expressions
When the page is requested, the expression is evaluated, converted to a string, and inserted into the output of the servlet's appropriate service method (doGet(), doPost(), etc.).
ex:
Here is the time:
2.2 Scriptlets
When the page is requested, the code is executed in the appropriate service method (doGet(), doPost(), etc.)
ex:
This is the same as
The color is:
2.2.1 Making parts of the JSP file conditional
Heads
Tails
2.2.2 Predefined Variables in Expressions and Scriptlets
Variable
|
Meaning
|
request
|
the
HttpServletRequest associated with the request
|
response
|
the
HttpServletResponse associated with the request
|
out
|
the
JspWriter used to send output to the client
|
session
|
the
HttpSession associated with the request
|
application
|
the
ServletContext obtained by getServletContext (the ServletContext is shared by
all servlets in the Web application, or all servlets in the servlet engine if
there is no Web application)
|
config
|
the
ServletConfig object for the page.
|
pageContext
|
the
PageContext (unique toJSP) object for the page
|
page
|
a synonym
for this
|
2.3 Declarations
The code is inserted into the body of the servlet class, outside of all methods.
ex:
Number of page hits:
2.3.1 Initialization and Cleanup in JSP Pages
For initialization and cleanup in JSP pages, use JSP declarations to override jspInit() and/or jspDestroy()
3. DIRECTIVES
A directive affects the overall structure of the servlet that results from the JSP page.
3.1 The page Directive
The page directive lets you import classes, set the content type, etc. It is the topic of section 4.
3.2 The include Directive
The include directive lets you insert a file into the servlet class. It is discussed in section 5.
3.3 The taglib Directive
The taglib directive is used to define custom markup tags. It is discussed in section 7.
4. THE page DIRECTIVE
A page directive lets you define the following attributes:
Attribute
|
Meaning
|
import
|
lets you
specify the classes that should be imported by the servlet
|
contentType
|
sets the
Content-Type response header
|
isThreadSafe
|
controls
whether or not the servlet will implement the SingleThreadModel interface
|
session
|
controls
whether or not the page participates in HTTP sessions
|
buffer
|
specifies
the size of the buffer used by the out variable
|
autoFlush
|
controls whether
the output buffer should be automatically flushed when it is full
|
extends
|
designates
the superclass of the servlet (usually already done by the server)
|
info
|
defines a
string that could be retrieved from the servlet by getServletInfo
|
errorPage
|
specifies a
JSP page that should process any exceptions thrown but not caught in the
current page
|
isErrorPage
|
indicates
whether or not the current page can act as the error page for another JSP
page
|
language
|
specifies
the underlying programming language
|
A page directive can be placed anywhere within the document
4.1 The import Attribute
The import attribute is probably the most commonly used attribute for page directives. It lets you specify the classes that should be imported by the servlet.
4.2 The errorPage and isErrorPage Attributes
The errorPage and isErrorPage attributes of a page directive control how thrown exceptions are handled. The errorPage attribute specifies a JSP page that should process any exceptions that are thrown but not caught in the current page.
The isErrorPage attribute indicates whether or not the current page can act as the error page for another JSP page.
Error pages have access to the thrown exception through a predefined variable named exception. Also, if an error page uses a jsp:include action, the flush attribute of that action must be omitted.
You may also take advantage of a JSP error page with a servlet using code similar to the following:
try {
// code that may generate an exception
}
catch (Exception e) {
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher( "myErrorPage.jsp");
request.setAttribute ("javax.servlet.jsp.jspException", e);
dispatcher.forward(request, response);
}
5. INCLUDING FILES IN JSP DOCUMENTS
The two main ways to include external pieces into a JSP document are the include directive and the jsp:include action.
1. The include Directive
Includes a file in the JSP document when the document is translated. Can be used to affect the main page as a whole but requires the servlets that use the file to be retranslated if the used file changes.
2. The jsp:include Action
Includes the output of a file at request time. It can't be used to affect the main page as a whole, but doesn't require files that use it to be retranslated when the used file changes.
5.1 The include Directive
The include directive includes a file in the JSP document when the document is tranlated into a servlet (the first time the page is accessed).
The included file can contain JSP declarations and response header settings that affect the main JSP page (the included JSP code itself is inserted into the main JSP page).
If the included file changes, however, all the JSP pages that use it must be retranslated (one can use the Unix touch command to reset their modification times).
ex:
5.2 The jsp:include Action
The preferred alternative to the include directive is the jsp:include action.
The jsp:include action includes the output of a page at request time.
The included file can contain JSP code, but not JSP code that affects the main JSP page (the output of the secondary page is included, not the code itself).
If the included file changes, the JSP files that use it do not have be retranslated.
ex:
6. USING JavaBeans WITH JSP
Beans are a convenient way to use your own classes in a JSP page.
Here are some points to remember about JavaBeans:
1. A bean class must have a zero-argument (empty) constructor.
2. A bean class should have no public instance variables (fields).
3. Persistent values should be accessed through methods called getXxx and setXxx. Boolean values are accessed by methods called isXxx and setXxx.
6.1 Basic Bean Use
Use the jsp:useBean action to load a bean to be used in the JSP page.
ex:
This can be thought to be equivalent to the following scriptlet:
One difference, however, is that a jsp:useBean action only creates a new bean if no bean with the same id and scope can be found. If a bean with the same id and scope is found, the preexisting bean is bound to the variable referenced by id.
By default, the local variable will be the same type as the bean class itself. Use the type attribute to make the local variable a superclass of the bean type or an interface that the bean type implements.
6.2 Accessing Bean Properties
The value of a bean property can be inserted into a JSP page in two ways:
or
The first approach is preferred because because Web page designers don't need to know Java syntax.
6.3 Setting Bean Properties
Setting a bean property can be done in two ways:
or
You may use a JSP expression for the value parameter. Specifically, you can set a bean property to the value of an input parameter to the JSP page. If the bean property is of type String, setting the value is straightforward:
However, if the bean property is a type other than String, then the input parameter must first be converted to the type of the bean property:
6.3.1 Associating Individual Properties with Input Parameters
The param attribute allows you to associate a property with a request parameter and automatically perform the type conversion from a String to the type of bean property:
You may wish to consider using error pages to catch exceptions when using automatic type conversions.
6.3.2 Associating All Properties with Input Parameters
You can also set all bean properties to their identically named input parameters in one statement via:
6.4 Sharing Beans
In addition to being local variables of the servlet's appropriate service method (doGet(), doPost(), etc.), beans can also be stored in one of 4 different locations, depending on the value of the optional scope attribute of jsp:useBean. The scope attribute can have one of these 4 values:
Location
|
Explanation
|
page
|
This is the
default value. Store the bean object in the PageContext object. You can then
get the bean by calling getAttribute() on the predefined pageContext
variable.
|
request
|
Store the
bean object in the ServletRequest object of the current request. You can then
call getAttribute() on the ServletRequest object. As the name suggests, the
object will be available only for the current request.
|
session
|
Store the
bean object in the HttpSession object associated with the current request.
You can then call getAttribute() on the HttpSession object. The object will be
available in this request and later requests from the same client.
|
application
|
Store the
bean object in theServletContext object. You can then get the bean by calling
getAttribute() on the ServletContext object. The ServletContext object is in
the predefined application variable or accessed via getServletContext(). The
ServletContext object is shared by all servlets in the same Web application
(or all servlets in the same webserver if no explicit Web applications are
defined). The object will be available in this request and later requests
from any client.
|
6.5 Conditional Bean Creation
A jsp:useBean action only creates a bean if no bean with the same id and scope can be found. If a bean with the same id and scope is found, the preexisting bean is bound to the variable referenced by id.
Instead of
you can use
The statements between the jsp:useBean start and end tags are executed only if a new bean is created. This is useful for initializing a newly created bean with jsp:setProperty actions.
7. DEFINING CUSTOM JSP TAGS
Three separate components must be defined to use custom JSP tags.
1. The tag handler class that defines the tag's behavior.
2. The tag library descriptor file that maps the XML element names to the tag implementations. The tag library descriptor file gives a name to the tag. It associates that name to a tag handler class.
3. The JSP file that uses the tag library .
The following sections will show how to take advantage of the different capabilities of custom tags.
7.1 A Basic Tag
7.1.1 The Tag Handler Class
A basic tag handler should extend TagSupport and override the doStartTag() method. doStartTag() is called at request time when the tag is found. For basic tags that don't have a tag body, doStartTag() should return SKIP_BODY. The following are some useful methods of the predefined pageContext variable.
Method
|
<>
>
Explanation
|
getOut()
|
<>
>
returns a
JspWriter instance to generate output
|
getRequest()
|
<>
>
returns a ServletRequest
which can be cast to HttpServletRequest
|
getRepsonse()
|
<>
>
returns a
ServletResponse which can be cast to HttpServletResponse
|
getServletContext()
|
<>
>
returns a
ServletContext
|
getSession()
|
<>
>
returns an
HttpSession
|
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
public class ExampleTag extends TagSupport {
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.print ("Tag Example");
} catch (IOException ioe) {
System.out.println ("Error in ExampleTag: " + ioe);
}
return SKIP_BODY;
}
}
7.1.2 The Tag Library Descriptor File
The tag library descriptor file gives names to tags and associates tag names to tag handler classes.
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
A tag library built by me.
7.1.3 The JSP File
JSP documents that make use of custom tags need to use the taglib directive, supplying a uri attribute that gives the location of the tag library descriptor file and a prefix attribute that specifies a short string that should preceed the tag name. The taglib directive may appear anywhere in the JSP page before the tag is used.
7.2 A Tag with Attributes
7.2.1 The Tag Handler Class
Adding support for an attribute named length is merely a matter of implementing the following method to your class that extends TagSupport (or otherwise implements the Tag interface):
public void setLength (String length) {
this.length = length;
}
It is a good idea to provide default values in the class for optional attributes.
7.2.2 The Tag Library Descriptor File
Tag attributes must be declared inside the tag element by means of an attribute element.
7.2.3 The JSP File
or
Note: most servers can't handle a combination of fixed strings and expressions in an attribute value, as in the following:
A workaround to this problem is to create a dummy string that holds the combination of strings and expression values, and then put this dummy string into the attribute value as a lone expression:
7.3 A Tag with a Body
7.3.1 The Tag Handler Class
To instruct the system to make use of the body that occurs between start and end tags, your doStartTag method should return EVAL_BODY_INCLUDE.
Override the doEndTag method to take some action after the tag body. The doEndTag method should return EVAL_PAGE to continue with the rest of the page or SKIP_PAGEto abort processing of the rest of the page.
public class ExampleTag extends TagSupport {
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.print ("");
} catch (IOException ioe) {
System.out.println ("Error in ExampleTag: " + ioe);
}
return EVAL_BODY_INCLUDE;
}
public int doEndTag() {
try {
JspWriter out = pageContext.getOut();
out.print ("");
} catch (IOException ioe) {
System.out.println ("Error in ExampleTag: " + ioe);
}
return EVAL_PAGE;
}
}
7.3.2 The Tag Library Descriptor File
For tags that use body content, the bodycontent element should contain the value JSP.
7.3.3 The JSP File
7.4 A Tag that Manipulates its Body
7.4.1 The Tag Handler Class
For tags that manipulate their body content, the tag handler should extend BodyTagSupport instead of TagSupport.
Override the doAfterBody method to handle the manipulation of the tag body. To manipulate the body once, return SKIP_BODY. To manipulate a body more than once, return EVAL_BODY_TAG for each iteration and then return SKIP_BODY on the last iteration.
An important method of BodyTagSupport is:
Method
|
<>
>
Description
|
<>
>
getBodyContent ()
|
<>
>
returns a BodyContent object
|
<>
>
Some important methods of BodyContent are:
Method
|
<>
>
Description
|
<>
>
getEnclosingWriter()
|
<>
>
returns the JSPWriter being used by
doStartTag and doEndTag
|
<>
>
getReader()
|
<>
>
returns a Reader that can read the tag's
body
|
<>
>
getString()
|
<>
>
returns a String containing the entire
tag body
|
<>
>
public class ExampleTag extends BodyTagSupport {
public int doAfterBody() {
BodyContent body = getBodyContent();
String bodyString = body.getString();
try {
JspWriter out = body.getEnclosingWriter();
manipulate (bodyString); // modify the bodyString in some way
out.println (bodyString);
} catch (IOException ioe) {
System.out.println ("Error in ExampleTag: " + ioe);
}
// return EVAL_BODY_TAG to handle the body again
return SKIP_BODY;
}
}
7.4.2 The Tag Library Descriptor File
Like all tags that use body content, the bodycontent element should contain the value JSP.
7.4.3 The JSP File
8. INTEGRATING SERVLETS AND JSP
The model view controller architecture approach to JSP uses a servlet to handle the initial request, partially process the data, set up beans, and then forward the result to one of a number of different JSP pages.
8.1 Request Forwarding
Request forwarding allows a servlet to transfer control to a different servlet or JSP on the same server:
// URL must be relative to the server root
String url = "/presentations/presentation1.jsp";
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url);
// forward control to a different servlet or JSP on same server
dispatcher.forward(request, response);
The URL of the original servlet is maintained. Therefore, all server-related URLs in your servlets and JSPs should be relative to the server root, not the page's location:
It is worth noting the difference beween the sendRedirect() method of HttpServletResponse and the forward() method of RequestDispatcher. When forward() is used, you are moving within the same webapp on the server side, preserving the URL of the original servlet. The request and response are also maintained. When sendRedirect() is used, a response with a status code of 302 (302 means Found, which most browsers treat the same as 301, Moved Permanently) is sent back to the browser, along with a Location response header giving the URL of the new document. The browser then sends a second request to the server, this time asking for the contents at the new URL. This is a new request for a new URL, which results in a new response. Neither sendRedirect() nor forward() can be called after a method of HttpServletResponse has already been called.
An alternative to completely transfering control to a new page is to merely include the content of a different servlet or JSP page on the same server:
// include the content of a different servlet or JSP on same server
dispatcher.include(request, response);
8.2 Storing Data for a JSP Page
There are three main places for the servlet to store the data that the JSP pages will use.
8.2.1 The Request
SomeClass value = new SomeClass();
request.setAttribute("key", value);
8.2.2 The Session
SomeClass value = new SomeClass();
HttpSession session = request.getSession(true);
session.setAttribute("key", value);
8.2.3 The Application
SomeClass value = new SomeClass();
getServletContext().setAttribute("key", value);