Section 3 - The Servlet
Container Model
3.1
Identify the uses for and the interfaces (or classes) and methods to achieve
the following features:
Servlet context init. parameters
Servlet context listener
Servlet context attribute listener
Session attribute listeners
3.2
Identify the WebApp deployment descriptor element name that declares the
following features:
Servlet context init. parameters
Servlet context listener
Servlet context attribute listener
Session attribute listeners
<
!--
The
context-param element contains the declaration of a web
application's
servlet context initialization parameters.
-->
<
!ELEMENT context-param (param-name, param-value, description?)>
<
!--
The
param-name element contains the name of a parameter. Each parameter
name
must be unique in the web application.
-->
<
!ELEMENT param-name (#PCDATA)>
<
!--
The
param-value element contains the value of a parameter.
-->
<
!ELEMENT param-value (#PCDATA)>
<
!--
The
listener element indicates the deployment properties for a web application
listener bean.
-->
<
!ELEMENT listener (listener-class)>
<
!--
The
listener-class element declares a class in the application must be registered
as
a
web application listener bean. The value is the fully qualified classname
of
the listener class.
-->
<
!ELEMENT listener-class (#PCDATA)>
<
!--
The
servlet element contains the declarative data of a
servlet.
If a jsp-file is specified and the load-on-startup element is
present,
then the JSP should be precompiled and loaded.
-->
3.3
Distinguish the behavior of the following in a distributable:
Servlet context init. parameters
Servlet context listener
Servlet context attribute listener
Session attribute listeners
Answered all at once:
Servlet API 2.3's second most
significant change is the addition of application lifecycle events, which let
"listener" objects be notified when servlet contexts and sessions are
initialized and destroyed, as well as when attributes are added or removed from
a context or session.
Servlet lifecycle events work like
Swing events. Any listener interested in observing the ServletContext
lifecycle
can implement the ServletContextListener
interface. The interface has two methods:
void
contextInitialized(ServletContextEvent e)
:
Called when a Web application is first ready to process requests (i.e. on
Web server startup and when a context is added or reloaded). Requests will
not be handled until this method returns. void
contextDestroyed(ServletContextEvent e)
:
Called when a Web application is about to be shut down (i.e. on Web server
shutdown or when a context is removed or reloaded). Request handling will
be stopped before this method is called. The ServletContextEvent
class passed to those methods has only a getServletContext()
method that returns the context being initialized or destroyed.
A listener interested in observing the ServletContext
attribute
lifecycle can implement the ServletContextAttributesListener
interface, which has three methods:
void
attributeAdded(ServletContextAttributeEvent e)
:
Called when an attribute is added to a servlet context void
attributeRemoved(ServletContextAttributeEvent e)
:
Called when an attribute is removed from a servlet context void
attributeReplaced(ServletContextAttributeEvent e)
:
Called when an attribute is replaced by another attribute in a servlet
context The ServletContextAttributeEvent
class extends ServletContextEvent
, and adds getName()
and getValue()
methods so
the listener can learn about the attribute being changed. That is useful
because Web applications that need to synchronize application state (context
attributes) with something like a database can now do it in one place.
The session listener model is similar to the context
listener model. In the session model, there's an HttpSessionListener
interface with two methods:
void
sessionCreated(HttpSessionEvent e)
: Called when a session
is created void
sessionDestroyed(HttpSessionEvent e)
: Called when a session
is destroyed (invalidated) The methods accept an HttpSessionEvent
instance with a getSession()
method to return the session being created or destroyed. You can use all these
methods when implementing an admin interface that keeps track of all active
users in a Web application.
The session model also has an HttpSessionAttributesListener
interface with three methods. Those methods tell the listener when attributes
change, and could be used, for example, by an application that synchronizes
profile data held in sessions into a database:
void
attributeAdded(HttpSessionBindingEvent e)
:
Called when an attribute is added to a session void
attributeRemoved(HttpSessionBindingEvent e)
:
Called when an attribute is removed from a session void
attributeReplaced(HttpSessionBindingEvent e)
:
Called when an attribute replaces another attribute in a session As you might expect, the HttpSessionBindingEvent
class extends HttpSessionEvent
and adds getName()
and getValue()
methods. The
only somewhat abnormal thing is that the event class is named HttpSessionBindingEvent
, not HttpSessionAttributeEvent
. That's for legacy reasons; the API already had an HttpSessionBindingEvent
class, so it was reused. This confusing aspect of the API may be ironed out
before final release.
A possible practical use of lifecycle events is a shared
database connection managed by a context listener. You declare the listener in
the web.xml as follows:
<listener>
<listener-class>
com.acme.MyConnectionManager
</listener-class>
</listener>
The server creates an instance of the listener class to
receive events and uses introspection to determine what listener interface (or
interfaces) the class implements. Bear in mind that because the listener is
configured in the deployment descriptor, you can add new listeners without any
code change. You could write the listener itself as something like this:
public class MyConnectionManager implements
ServletContextListener {
public void
contextInitialized(ServletContextEvent e) {
Connection con
= // create connection
e.getServletContext().setAttribute("con",
con);
}
public void contextDestroyed(ServletContextEvent
e) {
Connection con
= (Connection) e.getServletContext().getAttribute("con");
try {
con.close(); } catch (SQLException ignored) { } // close connection
}
}
This listener ensures that a database connection is available
in every new servlet context, and that all connections are closed when the
context shuts down.
The HttpSessionActivationListener
interface, another new listener interface in API 2.3, is designed to handle
sessions that migrate from one server to another. A listener implementing HttpSessionActivationListener
is notified when any session is about to passivate
(move) and when the session is about to activate
(become live) on the second host. These methods give an application the chance
to persist nonserializable data across JVMs, or to glue or unglue serialized
objects back into some kind of object model before or after migration. The
interface has two methods:
void
sessionWillPassivate(HttpSessionEvent e)
:
The session is about to passivate. The session will already be out of
service when this call is made. void
sessionDidActivate(HttpSessionEvent e)
:
The session has been activated. The session will not yet be in service
when this call is made. You register this listener just like the others. However,
unlike the others, the passivate and activate calls here will most likely occur
on two different servers!
Section 4 - Designing and
Developing Servlets to Handle Server-side Expectations
4.1
For each of the following cases, identify correctly constructed code for
handling business logic exceptions, and match that code with correct statements
about the code's behavior:
Return an HTTP error using the sendError response
method;
HttpServletResponse
sendError(int)
public void sendError(int sc)
Sends an error response to
the client using the specified status clearing the buffer. The server defaults
to creating the response to look like an HTML-formatted server error page,
setting the content type to “text/html”, leaving cookies and other headers
unmodified. If an error-page declaration has been made for the web application
corresponding to the status code passed in, it will be served back in
preference to the suggested msg parameter. If the response has already been
committed, this method throws an IllegalStateException. After using this
method, the response should be considered to be committed and should not be
written to.
Parameters:
sc - the error status code
Throws:
IOException -
If an input or output exception occurs
IllegalStateException - If
the response was committed
sendError(int,
String)
public void sendError(int sc,
java.lang.String msg)
Sends an error response to
the client using the specified status code and descriptive message. The server
generally creates the response to look like a normal server error page. If the
response has already been committed, this method throws an
IllegalStateException. After using this method, the response should be
considered to be committed and should not be written to.
Parameters:
sc - the error status code
msg - the descriptive
message
Throws:
IOException -
If an input or output exception occurs
IllegalStateException
- If the response was committed before this method call
Return an HTTP error using the setStatus method.
setStatus(int)
public void
setStatus(int sc)
Sets the status
code for this response. This method is used to set the return status code when
there is no error (for example, for the status codes SC_OK or
SC_MOVED_TEMPORARILY). If there is an error, and the caller wishes to invoke an
error-page defined in the web applicaion, the sendError method should be used
instead. The container clears the buffer and sets the Location header, reserving cookies and other headers.
Parameters:
sc - the status
code
4.2
Given a set of business logic exceptions, identify the following:
The configuration that the deployment descriptor
uses to handle each exception;
< !--
The web-app element is the root of the deployment descriptor for
a web application
-->
< !ELEMENT web-app (icon?, display-name?, description?, distributable?, context-param*, filter*, filter-mapping*, listener*, servlet*, servlet-mapping*, session-config?,
mime-mapping*, welcome-file-list?, error-page*, taglib*,
resource-env-ref*, resource-ref*, security-constraint*, login-config?, security-role*,
env-entry*, ejb-ref*, ejb-local-ref*)>
< !--
The error-page element contains a mapping between an error code
or exception type to the path of a resource in the web application
-->
< !ELEMENT error-page ((error-code | exception-type), location)>
< !--
The error-code contains an HTTP error code, ex: 404
-->
< !ELEMENT error-code (#PCDATA)>
< !--
The exception type contains a fully qualified class name of a
Java exception type.
-->
< !ELEMENT exception-type (#PCDATA)>
< !--
The location element contains the location of the resource in the
web application relative to the root of the web application. The value of
the location must have a leading `/'.
-->
How to use a RequestDispatcher to forward the
request to an error page;
Specify the handling declaratively in the deployment
descriptor.
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
<error-page>
<
exception-type>java.lang.NumberFormatException</
exception-type>
<location>/datavalidation.html</location>
</error-page>
4.3
Identify the method used for the following:
Write a message to the WebApp log;
Write a message and an exception to the WebApp log.
ServletContext.
log(String)
public void
log(java.lang.String msg)
Writes the specified message
to a servlet log file, usually an event log. The name and type of the servlet
log file is specific to the servlet container.
Parameters:
msg - a String specifying
the message to be written to the log file
log(String,
Throwable)
public void
log(java.lang.String message, java.lang.Throwable throwable)
Writes an explanatory
message and a stack trace for a given Throwable exception to the servlet log
file. The name and type of the servlet log file is specific to the servlet
container, usually an event log.