Sie sind auf Seite 1von 80

Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.

html

Copyright © 2002 Alx Dark

Revision 1.15 2004-03-25


Typos fixed.
Revision 1.14 2003-07-08
Minor typographic mistakes corrected, clarifications on relationship of doGet and
doHead methods.
Revision 1.13 2003-01-22

Preface
Contributors
Document Publication and Formats
The Servlet Model
For each of the HTTP methods, GET, POST, and PUT, identify the
corresponding method in the HttpServlet class.
HTTP GET
HTTP POST
HTTP PUT
For each of the HTTP methods, GET, POST, and HEAD, identify triggers
that might cause a browser to use the method, and identify benefits or
functionality of the method.
HTTP GET
HTTP POST
HTTP HEAD
For each of the following operations, identify the interface and method name
that should be used:
Retrieve HTML form parameters from the request
Retrieve a servlet initialization parameter
Retrieve HTTP request header information
Set an HTTP response header; set the content type of the response
Acquire a text stream for the response
Acquire a binary stream for the response

1 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Redirect an HTTP request to another URL


Identify the interface and method to access values and resources and to set
object attributes within the following three Web scopes:
Request
Session
Context
Given a life-cycle method: init, service, or destroy, identify correct statements
about its purpose or about how and when it is invoked.
init
service
destroy
Use a RequestDispatcher to include or forward to a Web resource
Getting the RequestDispatcher
Using the RequestDispatcher
The Structure and Deployment of Modern Servlet Web Applications
Identify the structure of a Web Application and Web Archive file.
Match the name with a description of purpose or functionality, for each of the
following deployment descriptor elements:
Servlet instance
Servlet name
Servlet class
Initialization parameters
URL to named servlet mapping
The Servlet Container Model
Identify the uses for and the interfaces (or classes) and methods to achieve
the following features:
Servlet context initialization parameters
Servlet context listener
Servlet context attribute listener
Session attribute listeners
Identify the WebApp deployment descriptor element name that declares the
following features:
Servlet context initialization parameters
Servlet context listeners, servlet context attribute listeners, session
listeners or session attribute listeners
Distinguish the behavior of the following in a distributable:
Servlet context initialization parameters
Servlet context listener
Servlet context attribute listeners
Session attribute listeners

2 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Designing and Developing Servlets to Handle Server-side Exceptions


Handling Business Logic Exceptions with HTTP Error Codes
sendError
setStatus
Handling Business Logic Exceptions Other Ways
Deployment Descriptors
RequestDispatcher
Web Application Logs
Designing and Developing Servlets Using Session Management
Identify the interface and method for each of the following:
Retrieve a session object across multiple requests to the same or
different servlets within the same WebApp
Store or retrieve objects from a session object
Respond to the event when a particular object is added to a session
Respond to the event when a session is created and destroyed
Expunge a session object
Given a scenario, state whether a session object will be invalidated
URL-rewriting
Designing and Developing Secure Web Applications
Identify correct descriptions or statements about the security issues:
Authentication, authorization
Data integrity
Auditing
Malicious code
Web site attacks
Identify the deployment descriptor element names, and their structure, that
declare the following:
A security constraint including a web resource
The login configuration
A security role
Types of authentication
BASIC
DIGEST
FORM
CLIENT-CERT
Designing and Developing Thread-safe Servlets
Identify which attribute scopes are thread-safe:
Local variables
Instance variables
Class variables

3 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Request attributes
Session attributes
Context attributes
Multi-threaded and single-threaded servlets
SingeThreadModel Interface
The Java Server Pages (JSP) Technology Model
Write the opening and closing tags for the following JSP tag types:
Directive
Declaration
Scriptlet
Expression
Given a type of JSP tag, identify correct statements about its purpose or use.
Directives
Declarations
Scriptlets
Expressions
Given a JSP tag type, identify the equivalent XML-based tags.
Directives
Declarations
Scriptlets
Expressions
Identify the page directive attribute, and its values, that:
Import a Java class into the JSP page
Declare that a JSP page exists within a session
Declare that a JSP page uses an error page
Declare that a JSP page is an error page
Identify and put in sequence the following elements of the JSP page
lifecycle:
Page translation
Match correct descriptions about purpose, function, or use with any of the
following implicit objects:
request
response
out
session
config
application
page
pageContext
Implicit object API

4 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Scoped collections API


Dispatching methods
JspWriters
Error handling
exception
Distinguish correct and incorrect scriptlet code for:
A conditional statement
An iteration statement
Designing and Developing Reusable Web Components
Given a description of required functionality, identify the JSP page directive
or standard tag in the correct format with the correct attributes to specify the
inclusion of a Web component into the JSP page.
Includes
Forwards
Designing and Developing JSP pages Using JavaBean Components
For any of the following tag functions, match the correctly constructed tag,
with attributes and values as appropriate, with the corresponding description
of the tag's functionality:
Declare the use of a JavaBean component within the page.
Specify, for jsp:useBean or jsp:getProperty tags, the name of an
attribute.
Specify, for a jsp:useBean tag, the class of the attribute.
Specify, for a jsp:useBean tag, the scope of the attribute.
Access or mutate a property from a declared JavaBean
Specify, for a jsp:getProperty tag, the property of the attribute
JSP/servlet scoped attribute implementations
request scope
session scope
application scope
Identify techniques that access a declared JavaBean component
Designing and Developing JSP pages Using Custom Tags
Taglibs in the deployment descriptor
Taglib directives
Given a custom tag library, identify properly formatted custom tag usage in a
JSP page. Uses include:
An empty custom tag
A custom tag with attributes
A custom tag that surrounds other JSP code
Nested custom tags
Designing and Developing a Custom Tag Library

5 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Identify the tag library descriptor element names that declare the following:
The name of the tag
The class of the tag handler
The type of content that the tag accepts
Any attributes of the tag
Identify the tag library descriptor element names that declare the following:
The name of a tag attribute
Whether a tag attribute is required
Whether or not the attribute's value can be dynamically specified
Given a custom tag, identify the necessary value for the bodycontent TLD
element for any of the following tag types:
Empty-tag
Custom tag that surrounds other JSP code
Custom tag that surrounds content that is used only by the tag handler
Given a tag event method (doStartTag, doAfterBody, and doEndTag),
identify the correct description of the methods trigger
doStartTag
doAfterBody
doEndTag
Identify valid return values for the following methods:
doStartTag, doAfterBody, doEndTag, PageContext.getOut
Given a BODY or PAGE constant, identify a correct description of the
constant's use in the following methods:
doStartTag
doAfterBody
doEndTag
Identify the method in the custom tag handler that accesses:
A given JSP page's implicit variable
Nested tags
Design Patterns
Given a scenario description with a list of issues, select the design pattern
that would best solve those issues
Value Object
MVC
Data Access Object
Business Delegate
Match design patterns with statements describing potential benefits that
accrue from the use of the pattern, for any of the following patterns:
Value Objects
MVC

6 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Data Access Object


Business Delegate
Sources

1. Directives
1. Attributes
1. Classes and Methods Required by Kind of Tag
2. Body Content Values
3. Tag Interface Lifecycle
4. IterationTag Interface Lifecycle
5. BodyTag Interface Lifecycle

Contributors
Document Publication and Formats

I prepared this study guide based on Sun's exam objectives for the Web Component
Developer certification. The organization and language of the objectives document are
not ideal. At times that document is ambiguous. Where necessary, I have looked at the
interpretations of other study guides for clarification. You can find other great resources
for the exam (including free practice exams) at the SCWCD links page at JavaRanch.

This study guide assumes that you have a strong knowledge of Java and some
familiarity with servlets and JSP, since these are both necessary before you'd consider
taking the exam.

I wrote this guide prior to taking the test and it contains no information about exam
questions. I passed with a 93% using this guide, but of course, I researched and wrote it
(I also rushed to get the certification before returning to work). While I can't make any
claims about this guide as an aide to your own performance on the exam, I think it is one
of the best study guides currently available.

Be aware that the certification itself does not cover everything in the servlet 2.3 and JSP
1.2 specifications (e.g., it doesn't cover filters or some of the newer application-level
listeners). The exam does focus on memorizing the APIs of the four packages in the
javax.servlet hierarchy. While you could pass this exam through rote memorization,

7 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

that would be the most painful way to do so. I found that the questions on servlets (my
strong suit) were easily answered based on experience with the technology.

Alright, enough talk, let's get started!

The following people have contributed corrections, suggestions, etc.:

Jorge Jordao, Amit Ghag, Seenu Maj, David Su, Pramila Thakur, Sijtsche Smeman, and
Anthony Beaty.

While the host site for this document may move, the latest version of this document
should always be available at http://purl.org/net/alxdark/wcd-guide.

You can view the entire guide on one page or on multiple pages if you wish. You can
also download a ZIP or TGZ bundle of the guide for reading off-line.

For each of the HTTP methods, GET, POST, and PUT, identify the corresponding
method in the HttpServlet class.
HTTP GET
HTTP POST
HTTP PUT
For each of the HTTP methods, GET, POST, and HEAD, identify triggers that
might cause a browser to use the method, and identify benefits or functionality of
the method.
HTTP GET
HTTP POST
HTTP HEAD
For each of the following operations, identify the interface and method name that
should be used:
Retrieve HTML form parameters from the request

8 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Retrieve a servlet initialization parameter


Retrieve HTTP request header information
Set an HTTP response header; set the content type of the response
Acquire a text stream for the response
Acquire a binary stream for the response
Redirect an HTTP request to another URL
Identify the interface and method to access values and resources and to set object
attributes within the following three Web scopes:
Request
Session
Context
Given a life-cycle method: init, service, or destroy, identify correct statements
about its purpose or about how and when it is invoked.
init
service
destroy
Use a RequestDispatcher to include or forward to a Web resource
Getting the RequestDispatcher
Using the RequestDispatcher

!" # $ %
& '

protected void doGet(HttpServletRequest req, HttpServletResponse res)


throws ServletException, java.io.IOException {
...
}

Called by the server to handle a GET request. If you override this method in
HttpServlet to provide functionality, the servlet container will provide support for the
doHead method by calling doGet and returning only the HttpServletResponse
headers (although it doesn't return the body to the client, it does use it to calculate length
headers).

Generally you use GET for operations that have no side effects, and that can be safely
repeated. For operations like database updates, POST is the accepted request type.

9 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

protected void doPost(HttpServletRequest req, HttpServletResponse res)


throws ServletException, java.io.IOException {
...
}

Called by the server to handle a POST request. An unlimited amount of information can
be sent to the server with such a request, as it is sent in the body of the request. POST
operations typically have side effects, and may not be repeatable (updating a database,
for example).

protected void doPut(HttpServletRequest req, HttpServletResponse res)


throws ServletException, java.io.IOException {
...
}

Called by the server to process a PUT request. It is used to post a file to the web server.
Obviously, the method has side effects.

!" # "( %
&& & )
% % '

GET is used to request a resource, like a file. Browsers can trigger such a request with a
hypertext link; to retrieve a resource that is listed in the href or src attribute of an
element; or if a form either has no action attribute, or an action value of GET, the
browser will use this method to send form data to the server.

Typically GET is used to retrieve a static resource, although a query string or extra path
information can be appended to the URL of a GET request in order to trigger server-side
processing. Such processing should not have side-effects and it should be repeatable.

10 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

POST is used to send form data to the server. It can generally only be triggered by
submitting a form that has its method set to the POST method. A POST can have
side-effects and may not be repeatable (for example, submitting payment for a
purchase).

A browser calls a HEAD request when it wants to examine the headers for a particular
resource, such as "Content-Type" or "Content-Length". Although such a request could
be used to examine the document's last modification time, a browser can also send the
"If-Modified-Since" header in a request, against which the server can compare a
resource and determine whether or not it should send the new version, or a 304 (Not
Modified) status code. This feature works with the browser's caching ability to reduce
downloads. HTTP servlets that support GET requests can implement the
getLastModified method to support this feature (otherwise the servlet will always
appear modified and its content body will always be returned).

) & %
*

! "#

public interface javax.servlet.ServletRequest {


public String getParameter(String name);
public java.lang.String[] getParameterValues(String name);

public java.util.Enumeration getParameterNames();


public java.util.Map getParameterMap();
}

The obvious and easy way to retrieve a value is req.getParameter("myValue").


The more robust version of this method is getParameterValues which returns all the
values for that key (in HTTP form data there can be more than one); the
getParameter method will only return the first value if there is more than one.

Where values are sent both in the query string and in the body of the HTTP request, the
values are all added into the collection of parameters available through this API; the
query string parameters will appear first in the collection.

11 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

The parameter API could be used for other protocols than


HTTP; it is defined in the ServletRequest interface.

Where you do not know the parameters in advance, getParameterNames can be


helpful. It is most often used for debugging. The final method returns a Map interface
(see the Collections Tutorial by Sun).

public interface javax.servlet.ServletConfig {


public String getInitParameter(String name);
public java.util.Enumeration getInitParameterNames();
}

Self explanatory. These initialization parameters are set in the deployment descriptor.

"# ! %

public interface javax.servlet.http.HttpServletRequest {

public String getHeader(String name);


public java.util.Enumeration getHeaders(String name);
public java.util.Enumeration getHeaderNames();

public long getDateHeader(String name);


public int getIntHeader(String name);
}

There are special methods for retrieving headers that are dates or integers. They throw
IllegalArgumentException and NumberFormatException respectively, if they
are called on headers that cannot be converted to these formats. If these accessor
methods are called on a header that doesn't exist, they return null or -1 depending on
the return type. Finally, there is a method for getting a header that is set multiple times in
the request, and for getting all the header names in the request (e.g. "Cache-Control").
The last is useful for debugging and reporting.

! % & ! ' !

12 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public interface javax.servlet.http.HttpServletResponse {

// Can be used to test if a header has already been set


public boolean containsHeader(String name);

// Mutator methods
public void setHeader(String name, String value);
public void setIntHeader(String name, int value);
public void setDateHeader(String name, long value);
}

public interface javax.servlet.ServletResponse {


public void setContentType(String type);
}

Analogous to the access methods, there are special methods for setting headers that
represent integer and date values.

setContentType takes a String value that consists of two parts: a MIME type,
followed by an optional encoding (with the two separated by a semicolon). Examples
include "text/plain" and "text/html; UTF-8". You have to set the content type prior to
getting the PrintWriter for the response.

'"# !

public interface javax.servlet.ServletResponse {


public java.io.PrintWriter getWriter();
}

Prior to calling this method, you may set the encoding of the PrintWriter by calling
the setContentType method with a String argument that includes the mime type
and optionally, an encoding to use (e.g. "text/plain; UTF-8"). You can send a response to
the client with either the PrintWriter or the ServletOutputStream provided by the
getOutputStream method, but you cannot use both. An attempt to do so will throw an
IllegalStateException. Calling flush on the PrintWriter will commit the
response.

'"# !

13 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public interface javax.servlet.ServletResponse {


public javax.servlet.ServletOutputStream getOutputStream();
}

You can send a response to the client with either the ServletOutputStream or the
PrintWriter provided by the getWriter method, but you cannot use both. An
attempt to do so will throw an IllegalStateException. Calling flush on the
ServletOutputStream will commit the response.

% ' "# !

public interface javax.servlet.http.HttpServletResponse {


public void sendRedirect( String location );
}

Sends a temporary redirect (HTTP code 307) to the browser with a Location header
directing the browser to a new URL.

The method accepts a relative URL (the container generates the necessary absolute
URL). One might expect that an URL beginning with a slash (e.g. "/alxdark/test.html")
would be mapped relative to the context path of the web application, but it is not, it is
mapped from the server root. Calling this method after committing part of the response
will throw an IllegalStateException.

The URL string passed to this method can and probably should be passed through
another HttpServletResponse method, encodeRedirectURL, in order to support
URL rewriting where sessions are required and cookies are disabled:

res.sendRedirect( res.encodeRedirectURL( "../etc/second.html" ) );

+ %
, ) ) &
*

"#

14 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public interface javax.servlet.ServletRequest {


public Object getAttribute( String name );
public java.util.Enumeration getAttributeNames();
public void setAttribute( String name, Object object );
public void removeAttribute( String name );

public ServletInputStream getInputStream();


public BufferedReader getReader();
}

There's very little remarkable about these methods. The ServletRequest object has a
collection associated with it. If you pass a null reference to an object in the
setAttribute method, it's the equivalent of calling removeAttribute with the same
name argument. If there are no attributes, getAttributeNames will return an empty
Enumeration.

As the objectives also mention resources, note that the body of the request can be
retrieved as a binary stream or a character stream using the getInputStream and
getReader methods, respectively.

public interface javax.servlet.http.HttpSession {


public Object getAttribute( String name );
public java.util.Enumeration getAttributeNames();
public void setAttribute( String name, Object object );
public void removeAttribute( String name );
}

The HttpSession object has a collection associated with it. If you pass a null reference
to an object in the setAttribute method, it's the equivalent of calling
removeAttribute with the same name argument. If there are no attributes,
getAttributeNames will return an empty Enumeration.

public interface javax.servlet.ServletContext {


public Object getAttribute( String name );
public java.util.Enumeration getAttributeNames();
public void setAttribute( String name, Object object );
public void removeAttribute( String name );

15 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public URL getResource( String path );


public InputStream getResourceAsStream( String path );
}

The ServletContext object has a collection associated with it. If you pass a null
reference to an object in the setAttribute method, it's the equivalent of calling
removeAttribute with the same name argument. If there are no attributes,
getAttributeNames will return an empty Enumeration.

As far as accessing resources, the ServletContext object provides two invaluable


methods, getResource and getResourceAsStream, which provide access to any
resource (file) in the web application. The path must begin with a "/" and it is interpreted
relative to the context root of the application (you can access files in the META-INF/ and
WEB-INF/ directories with these methods).

! - % * % %
) )
. '

The init method is called on a servlet instance right after it has been initialized (the
servlet container calls a zero-argument constructor). The method can be overridden in a
subclass to provide one-time initialization of the servlet (e.g. reading in properties from a
properties file). If for some reason this initialization fails, you should throw an
UnavailableException (note that this exception can take an int argument
specifying how long the server should wait before attempting to instantiate the servlet
again). If the init method does not complete successfully, the servlet is not brought
into service.

'

Once a servlet is successfully put into service, the service method is called each time
a request is processed by the servlet. This can happen concurrently from multiple
threads, unless the servlet implements the SingleThreadModel tag interface.

16 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Once all pending service requests have exited the service method, the destroy
method can be invoked just before a servlet is taken out of service by the servlet
container (dereferenced and garbage-collected). It is similar to the finalize method
available to all Java objects, and you would use it to release resources, save state
information, and the like.

When will a servlet will be taken out of service? This depends on the servlet container,
although shutting the container down is surely one case where all active servlets will be
taken out of service.

$ / 0 )

( ! RequestDispatcher

The ServletContext interface provides two methods to acquire a


RequestDispatcher:

public interface javax.servlet.ServletContext {


public javax.servlet.RequestDispatcher getRequestDispatcher(String url);
public javax.servlet.RequestDispatcher getNamedDispatcher(String name);
}

getRequestDispatcher takes an url argument that must begin with a "/" and
represents a path within the current servlet context. The getNamedDispatcher
method allows you to use the name of a servlet as defined in the deployment descriptor.
This approach provides some additional flexibility as you can re-arrange application
components at a later time.

Previous versions of this study guide described


getRequestDispatcher as a method to dispatch across
contexts; this is not correct (thanks to Jorge Jordao for pointing
this out).

You can also use a relative path to obtain a getRequestDispatcher through the use
of another method on the request object:

17 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public interface javax.servlet.ServletRequest {


public javax.servlet.RequestDispatcher getRequestDispatcher(String url);
}

The path provided to this method is relative to the calling servlet.

Query strings can be appended to the URLs provided to these methods; these additional
parameters will be available in the request object's parameter collection (where they
appear first in the collection before other parameters). However, they fall out of scope
after the include or forward call.

( ! RequestDispatcher

The code for using a RequestDispatcher is straightforward:

// Just for the sake of illustration


req.setAttribute("us.alxdark.myApp", someObj);
// Get dispatcher with a relative URL
RequestDispatcher dis = req.getRequestDispatcher("../someUrl.html");
// include
dis.include(req, res);
// or forward
dis.forward(req, res);

When using the include method, the called servlet can only alter the body of the
response, and not the headers. The path information of the request also continues to
reflect the original request location.

When using the forward method, no content may have been committed to the client,
but the called servlet can adjust the headers as well as the body of the response
(content produced up to the forward call is cleared from the buffer). The path information
of the request is altered to reflect the location of the called servlet, and no further
output can occur after returning from a forward call (the output is committed upon
returning from the call).

RequestDispatcher objects obtained with the


getNamedDispatcher method behave differently than other
such objects. As discussed here, forward calls do not involve
an adjustment of the object's parameters to reflect the path of

18 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

the called servlet.

%
(

Identify the structure of a Web Application and Web Archive file.


Match the name with a description of purpose or functionality, for each of the
following deployment descriptor elements:
Servlet instance
Servlet name
Servlet class
Initialization parameters
URL to named servlet mapping

+ % ( (
'
Web archive files (jar files with the .war file extension) contain certain standard
directories and files. If you decompress a web application packaged as antwerp.war,
you will at least see the following directories and files:

index.html
[etc.]
images/
[etc.]
META-INF/
MANIFEST.MF
WEB-INF/
classes/
lib/
web.xml

The root directory can contain any files or folders that compose the web site, such as
images, HTML and/or JSP pages. There are also two additional folders, META-INF/
and WEB-INF/, that are not directly accessible to web browsers (the servlet container

19 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

will not directly serve files in these folders, but they are still accessible to the developer
through the getResource and getResourceAsStream methods of the
ServletContext interface).

The META-INF/ folder serves exactly the same purpose and function as it does in any
other jar file.

The web application deployment descriptor file is named web.xml and it is located in
the WEB-INF/ directory. Jar files (including custom tag library jar files) are located in a
lib/ directory, while other code files such as servlets are located in a classes/
directory. These last two directories are a well-known Java convention, but their location
under the WEB-INF/ directory is unique to web applications.

Custom tag libraries have their own deployment descriptor called a Tag Library
Descriptor (a .tld file). You have some options about where to place the TLD file as well
as the tag class files. Unbundled, you can place the TLD file anywhere in the WEB-INF/
directory, and then reference it directly in a taglib directive:

<%@ taglib uri="/WEB-INF/tlds/my-tags.tld" prefix="mine" %>

You can also map the URI declared in the taglib directive to an actual directory path
using a declaration in the web.xml file. Here's a sample declaration in a JSP page:

<%@ taglib uri="/my-tags" prefix="mine" %>

And how it would be mapped to an actual file:

<taglib>
<taglib-uri>/my-tags</taglib-uri>
<taglib-location>/WEB-INF/tlds/my-tags.tld</taglib-location>
<taglib>

In addition, custom tag libraries can be bundled as JAR files. In this case, the TLD file
must be located in the WEB-INF/ directory of the jar file. In the taglib directive, the
URI attribute points to the jar file just as you would include a jar file on your classpath
(e.g. /WEB-INF/lib/myTags.jar).

) %

20 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

) & % *

'

All of 2.2 discusses the declaration of a servlet and a servlet mapping in the deployment
descriptor file. Here's an example using most of the elements of the declaration:

<web-app>

<servlet>
<servlet-name>test</servlet-name>
<display-name>Test Servlet</display-name>
<description>A test servlet for illustration purposes.</description>
<servlet-class>us.alxdark.test.TestServlet</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>Alx</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
...
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test/*</url-pattern>
</servlet-mapping>
...
<security-role>
<description>PHBs at the company.</description>
<role-name>manager</role-name>
<security-role>

</web-app>

The servlet tag serves four purposes:

It describes meta-data for manipulating the servlet in a development environment,


and for loading the servlet in a servlet container;

It provides a name for the servlet that is unique to the application (and it can make
different instances of the same servlet class available under different names);

It provides initialization parameters that can be changed without recompiling the


servlet;

It allows the developer to declare information about the security model to be used

21 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

when running the servlet.

The DTD for the servlet tag includes many other optional elements:

<!ELEMENT servlet (icon?, servlet-name, display-name?, description?,


(servlet-class|jsp-file), init-param*, load-on-startup?, run-as?,
security-role-ref*)>

<servlet>
...
<servlet-name>test</servlet-name>
<servlet-class>us.alxdark.test.TestServlet</servlet-class>
...
</servlet>

The logical name for the servlet allows you to decouple references to a servlet from its
implementation class. For example, you can acquire a RequestDispatcher via the
logical name of a servlet or JSP page. Later, if you need to change the class of the
servlet, you can simply adjust the deployment descriptor and avoid changing your
RequestDispatcher code.

<!ELEMENT servlet-mapping (servlet-name, url-pattern)>

'

<servlet>
...
<servlet-name>test</servlet-name>
<servlet-class>us.alxdark.test.TestServlet</servlet-class>
...
</servlet>

The class declaration specifies the implementing servlet for this declared servlet
instance. It's a string that declares the fully-qualified name of a class implementing the
Servlet interface.

) $

22 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<web-app>

<context-param>
<param-name>dbConnections</param-name>
<param-value>10</param-value>
<description>Number of connections maintained by the DB connection
pool. The default is 10.</description>
</context-param>

<servlet>
...
<init-param>
<param-name>name</param-name>
<param-value>Alx</param-value>
</init-param>
...
</servlet>

</web-app>

Any number of initialization parameters can be declared for the application/context as a


whole, or for any individual JSP/servlet. The context-param tag occurs near the top of
the deployment descriptor and describes parameters for the application. Within the
servlet tag there is an init-param tag that serves the same purpose. The values can
be retrieved using the following methods (note that GenericServlet and
HttpServlet implement the ServletConfig interface):

public String ServletContext.getInitParameter(String name);


public Enumeration ServletContext.getInitParameterNames();

public String ServletConfig.getInitParameter(String name);


public Enumeration ServletConfig.getInitParameterNames();

These parameters allow an administrator or deployment developer to change specific


values in the application even after it is compiled and packaged. This allows for a certain
amount of customization after development.

% (

<web-app>
<servlet>
</servlet>

23 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

...
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test/*</url-pattern>
</servlet-mapping>
</web-app>

The URL to servlet mapping allows you to decouple references to a servlet from a
specific URL. Instead you can declare that a servlet should handle requests directed to
any page, directory or file type in the application. The benefits are obvious enough, but
the mapping rules are somewhat complex.

Page mappings include the entire URL, as so: /somepath/thispage.html;

Path mappings are specified as so: /somepath/*;

File type/extension mappings are mapped as so: *.ext

A default servlet for the application is indicated with the / mapping.

A request URL (minus the context path and everything to the left of it) is evaluated by
each of the following rules, in order, until a match is made:

If there's an exact match, it is selected;

Working up the directories specified by the mapping, attempt to match against a


mapping (such that the longest mapping that applies will be selected);

If this doesn't work, and the mapping has an extension mapping (e.g. *.jsp), use
the servlet assigned to that extension;

If there is still no match, attempt to use a default servlet for handling such requests
(e.g. a servlet that returns the file at that physical directory location, if it exists).

These mappings are tricky (at least to my mind) because they are different than how
web servers resolve similarly ambiguous URL paths. I suggest a review of the servlet 2.3
specification, page 77, where examples of these mappings are given.

24 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Identify the uses for and the interfaces (or classes) and methods to achieve the
following features:
Servlet context initialization parameters
Servlet context listener
Servlet context attribute listener
Session attribute listeners
Identify the WebApp deployment descriptor element name that declares the
following features:
Servlet context initialization parameters
Servlet context listeners, servlet context attribute listeners, session listeners
or session attribute listeners
Distinguish the behavior of the following in a distributable:
Servlet context initialization parameters
Servlet context listener
Servlet context attribute listeners
Session attribute listeners

+ % 1 2
) & *

' $

public String ServletContext.getInitParameter(String name);


public Enumeration ServletContext.getInitParameterNames();

Any number of initialization parameters can be declared for the application/context as a


whole. Servlet implementations based on GenericServlet or HttpServlet
implement the ServletConfig interface, so they can simply call
getServletContext() to access these methods.

These parameters allow an administrator or deployment developer to change specific


values in the application even after it is compiled and packaged. This allows for a certain
amount of customization after development. A typical example is setting the number of
connections to be maintained by a database pool.

'

25 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public interface javax.servlet.ServletContextListener {


public void contextDestroyed(ServletContextEvent sce);
public void contextInitialized(ServletContextEvent sce);
}

A servlet context listener is declared in the deployment descriptor. You might use this
listener to log on to a database and store a connection as a servlet context attribute.
When the context is destroyed, the connection could be closed. The event passed to the
listener provides a method for obtaining a reference to the ServletContext that has
started or stopped:

public class javax.servlet.ServetContextEvent {


public ServletContext getServletContext();
}

' #

public interface javax.servlet.ServletContextAttributeListener {


public void attributeAdded(ServletContextAttributeEvent e);
public void attributeRemoved(ServletContextAttributeEvent e);
public void attributeReplaced(ServletContextAttributeEvent e);
}

This listener must be registered in the deployment descriptor. An example of its use
might be to implement a class that logs the addition or removal of database connections
to the servlet context attribute collection. The event passed to this listener provides the
ability to get the servlet context, the attribute name and the object that was involved in
the event:

public class javax.servlet.ServetContextAttributeEvent


extends ServetContextEvent {
public ServletContext getServletContext();
public String getName();
public Object getValue();
}

26 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public interface javax.servlet.http.HttpSessionAttributeListener {


public void attributeAdded( HttpSessionBindingEvent se );
public void attributeRemoved( HttpSessionBindingEvent se );
public void attributeReplaced( HttpSessionBindingEvent se );
}

An example of the use of this interface would be an object that kept track of the names
of users who were logged in to an application (as measured by active sessions). The
event passed to this listener provides the ability to get the session, the attribute name
and the object that was involved in the event:

public class javax.servlet.http.HttpSessionBindingEvent


extends HttpSessionEvent {

public String getName();


public Object getValue();
public HttpSession getSession();
}

There are other listeners that are not mentioned in the


objectives document. They are the HttpSessionListener,
the HttpSessionActivationListener and the
HttpSessionBindingListener interfaces. If I remember
correctly, these interfaces are referenced during exam
questions about distributed applications; you'd best be familiar
with them if only to differentiate them from the interfaces
covered by the exam.

+ % ( %
) & *

' $

<web-app>

<context-param>

27 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<param-name>dbConnections</param-name>
<param-value>10</param-value>
<description># connections in DB connection pool.</description>
</context-param>

<listener>
<listener-class>us.alxdark.test.LogDbConnections</listener-class>
</listener>

</web-app>

Here's the DTD for this portion of the deployment descriptor:

<!ELEMENT context-param (param-name, param-value, description?)>

' * ' # *
#

<web-app>

<context-param>
<param-name>dbConnections</param-name>
<param-value>10</param-value>
<description># connections in DB connection pool.</description>
</context-param>

<listener>
<listener-class>us.alxdark.test.LogDbConnections</listener-class>
</listener>

</web-app>

List the listeners in the order in which they are to be notified of an event. The declaration
in web.xml is identical for all of the following four listeners:
ServletContextListener, ServletContextAttributeListener,
HttpSessionListener, HttpSessionAttributeListener.

The DTD for this simple element is:

<!ELEMENT listener (listener-class)>

28 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

& ) & *

' $

The parameters are local to the virtual machine (VM) in which they are created. If
information needs to be shared between servlets in a distributed environment, it should
be placed in a session (which migrates with the user between servers), or a store such
as a database, EJB, or directory service.

'

Events are not required to propagate between different virtual machines (VMs) in a
distributed application (presumably you have servers running on different machines
within or alongside different VMs). Consequently, each servlet context listener will
receive notification of application startup and shutdown, but it won't be the same event in
each VM/server involved.

' #

Again, events don't propagate between VMs (or between servers, assuming the two are
related to one another, which they needn't be). As a consequence, a listener in a VM will
only see events based on attribute changes to the servlet context in that VM.

Again, events don't propagate between VMs (or between servers, assuming the two are
related to one another, which they needn't be). If an event is fired by an HttpSession,
the only listeners that will be notified are those listeners that are in the VM currently
servicing the request associated with that session. Over the course of a session, the
session object may migrate between servers (to address load balancing, for example),
so the listener instances could change.

Once again, you might review the behavior of the following


listeners in a distributed application: HttpSessionListener,
HttpSessionActivationListener and
HttpSessionBindingListener. However, I don't remember
being asked about this on the exam (I could be wrong)!

29 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

& & & -


"3

Handling Business Logic Exceptions with HTTP Error Codes


sendError
setStatus
Handling Business Logic Exceptions Other Ways
Deployment Descriptors
RequestDispatcher
Web Application Logs

&4 5 & "3 ) "

public interface javax.servlet.http.HttpServletResponse {


public void sendError(int errorCode);
public void sendError(int errorCode, String message);
}

The error code is an HTTP status code, usually an "Internal Server Error" (500) or a
"Service Unavailable" error (503). There are others, however, all indicated with
HttpServletResponse constants. When using this method, the servlet container will
either use a custom error servlet/JSP page for the error code (as specified by the
developer in the deployment descriptor), or if none is specified, a generic error page will
be provided by the container.

Here's an example of using this method from Hunter and Crawford's Java Servlet
Programming, 2nd ed. (O'Reilly 2001):

try {
ServletUtils.returnFile(file, out);
} catch(FileNotFoundException e) {
res.sendError(res.SC_NOT_FOUND);
}

30 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

This method has to be called before the response is committed, or it will throw an
IllegalStateException. If a message is included, it will be incorporated into the
server's error page.

Like sendError, the setStatus method must be called before any content is
committed to the response. Unlike the error method, it can be used to set any status
(including non-error status codes), and the servlet is still responsible for providing the
body of the response to the client. The real issue is not how to use these methods, so
much as when to use one method over another. For errors, sendError is usually
desirable. You can specify custom error pages in the web deployment descriptor, either
to handle specific exceptions or to handle error codes.

&4 5 & "3 # %

'

As an example, let's say we wanted ServletExceptions to be displayed in a custom


response created by the ErrorServlet servlet, and we had a JSP page to handle 404
errors. Here's how that might look in the deployment descriptor:

<web-app>
...
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/errors/ErrorServlet</location>
</error-page>

<error-page>
<error-code>404</error-code>
<location>/errors/404.jsp</location>
</error-page>
...
</web-app>

The servlet would need an additional servlet-mapping entry to connect the dots. If
you do not specify these error handlers in your deployment descriptor, the servlet/JSP
container will provide a default error page that is used for the server as a whole.

The DTD for this element is as follows:

31 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<!ELEMENT error-page ((error-code|exception-type),location)>

"# '!

If you have a method that throws an application-specific error, like MyException, then
the following code would initiate the handling of that exception:

public void doGet(HttpServletRequest req, HttpServletResponse res) {


...
try {
someMethod( name );
} catch(MyException me) {
req.setAttribute("us.alxdark.test.MyException",me);
RequestDispatcher dis = req.getRequestDispatcher("../error");
dis.forward(req, res);
}
...
}

In the servlet handling the error you would do something with the exception, like the
following:

public void doGet(HttpServletRequest req, HttpServletResponse res) {


MyException me =
(MyException)req.getAttribute("us.alxdark.test.MyException");

// Some lame error reporting code


res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.println( me.getMessage() );
}

( 5 &

public interface javax.servlet.ServletContext {


public void log(String message);
}

Writes the message to a server log. Contrary to the way this objective is written, the

32 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

log's location is determined by the server, and may include all applications running on
the server.

This version of the log method will print a stack trace to the server log:

public interface javax.servlet.ServletContext {


public void log(String message, Throwable t);
}

& & & $ & &

Identify the interface and method for each of the following:


Retrieve a session object across multiple requests to the same or different
servlets within the same WebApp
Store or retrieve objects from a session object
Respond to the event when a particular object is added to a session
Respond to the event when a session is created and destroyed
Expunge a session object
Given a scenario, state whether a session object will be invalidated
URL-rewriting

+ % ) &*

+ ' ' # "# ! %


, ! ! -

public interface javax.servlet.http.HttpServletRequest {


public HttpSession getSession();
public HttpSession getSession(boolean create);
}

The first version with no arguments will produce a session if it does not yet exist; the
second version allows the possibility of suppressing this behavior with a false value.

+ ' + '

33 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public interface javax.servlet.http.HttpSession {


public void setAttribute(String name, Object value);
public Object getAttribute(String name);
public Enumeration getAttributeNames();
public void removeAttribute(String name);
}

All pretty obvious. Works like the collections on the request or context objects.

% ! ,! '# + ' %% %

There are two interfaces for this event; one notifies the object itself when it is bound or
unbound to the session, and the other (newer) interface notifies another object not
involved in the event. Here's the first listener that notifies an object that it is being bound
or unbound to the session as an attribute:

public interface javax.servlet.http.HttpSessionBindingListener {


public void valueBound( HttpSessionBindingEvent e );
public void valueUnboud( HttpSessionBindingEvent e );
}

In addition, you can implement the HttpSessionAttributeListener so that another


object can receive notification when an attribute is added, updated or removed. This
interface, and the event object that both these interfaces share
(HttpSessionBindingEvent) are described in section 3.1.

% ! ,! ' % %% %

javax.servlet.http.HttpSessionListener {
public void sessionCreated(HttpSessionEvent e);
public void sessionDestroyed(HttpSessionEvent e);
}

The event passed to the listener allows access to the session:

public javax.servlet.http.HttpSessionEvent {
public HttpSession getSession();
}

# ( + '

34 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public interface javax.servlet.http.HttpSession {


public void invalidate();
}

Throws an InvalidStateException if called on an already invalid session. The


container will unbind any objects bound to the session (calling the appropriate listeners
as it does so) before it dereferences the session.

! ) , )

One obvious scenario where the session will be invalidated is when a user times out of
the session (because he or she has not made a request within the specified period). The
timeout period is defined by the servlet container although it can be accessed and
changed through the HttpSession.getMaxInactiveInterval and
setMaxInactiveInterval(int seconds) methods. In practice questions, you
needed to know that setting the timeout interval to -1 disables timeouts.

You can specify a timeout value in the deployment descriptor. Here is an example where
the timeout is set to 40 minutes:

<session-config>
<session-timeout>40</session-timeout>
</session-config>

The HttpSession methods set and read the timeout value in


seconds, while the deployment descriptor sets the timeout value
in minutes.

$/5- ) &
URL rewriting involves placing the session key (normally stored as jsessionid in a
browser cookie) as a parameter in every HTML link in a web page. This is necessary
when a browser has cookie support disabled. Every URL written out by a servlet or JSP
page should be run through the following methods in the servlet API:

35 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public String HttpServletResponse.encodeURL( String url );


public String HttpServletResponse.encodeRedirectURL( String url );

The latter method is used to encode any URL used as an argument in the
sendRedirect method. If the user's browser does support cookies, the URLs are
simply returned unchanged. Session tracking via URLs can lead to a single browser
supporting multiple sessions through several windows.

There are methods for determining whether a session is being supported via cookies or
URL rewriting, and whether or not the session reported by a request is still valid or not.
Typically you won't need these methods, because attempting to get an invalid session
with getSession will either return null, or a new session, depending on the overloaded
method you use.

There's no JSP tag in the JSP 1.2 specification for doing URL rewriting (although it is in
the JSP Standard Tag Library).

& & & (

Identify correct descriptions or statements about the security issues:


Authentication, authorization
Data integrity
Auditing
Malicious code
Web site attacks
Identify the deployment descriptor element names, and their structure, that declare
the following:
A security constraint including a web resource
The login configuration
A security role
Types of authentication
BASIC
DIGEST
FORM
CLIENT-CERT

36 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

+ % %
*

# ! ' * # ! $

Objective 6.1 asks open-ended questions about web security,


which cannot be fully addressed here. However, if you have any
web application development experience, I think you'll find the
questions are not difficult to answer. It's a case of knowing your
ass from your elbow.

Authentication involves verifying the identities of entities involved in an exchange, while


authorization involves the controlled access to resources based upon an entity's identity.

Obviously, authorization requires successful authentication. Although a user name and


password can authenticate a user, a more secure form of authentication uses the
exchange of "digital certificates" for public key encryption (SSL uses this method). These
certificates combine a cryptographic key with the identification of an owner, and the
agencies that issue these certificates make some effort to verify that the owner is the
party identified by the certificate.

Data integrity involves verification that the content of a communication has not been
changed in transit.

One issue here is that HTTP is conducted on top of TCP/IP, and neither are encrypted.
It is possible that a "man-in-the-middle" attack could be used to intercept and change the
contents of such communications. SSL addresses this issue as a protocol layered
between TCP/IP and HTTP that encrypts the contents of these packets. This provides
solid assurance they are being delivered uncorrupted.

#% (

Auditing (maintaining logs on server usage) can allow an administrator to keep track of
and/or reconstruct unusual activity such as attacks on the application. They are also a
security liability insofar as they should be protected from intruders and prevented from
growing so large that they crash a machine (which can happen).

37 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

' # ' %

You are using Java in a JVM, so the security issues are similar to the security issues in
any other Java application. However, in a situation where you are executing
containerized code, there are some additional security concerns. For example, calling
System.exit(0) from within a servlet may cause the servlet container to shut down.

In recent flavors of Java, security issues such as these are dealt with through the use of
a Security Manager. For example, Tomcat gives you the ability to define security policies
in a properties file that hold for all applications running on that Tomcat server.

The specification suggests that an application should not have access to files related to
the servlet container, and indeed, it may have no access to files outside of the context
directory with the exception of a temporary working directory provided by the container.

- '

Rather obviously, they are a security issue.

All I can do here is provide an example and its impact on the application developer. A
denial of service (DOS) attack involves sending massive numbers of requests to a
server in a short period of time so that the server can no longer respond to legitimate
requests. How well your application responds to such an attack depends on the extent of
the resources you tie up to process specific requests. To minimize the impact of such an
attack you should not use dynamic methods to serve essentially static resources; create
and dereference resources that could be pooled and reused; or allocate sessions where
session state is not required. In short, the attacker should have to work hard (too hard!)
to overwhelm the resources of the server.

+ % %
) &*

'# ' ' #% ( , # '

Once you have authenticated a user as belonging to a particular role (see 6.2.4), you
can declaratively set constraints on what that user can do with a web application. Here's
the example from the servlet 2.3 specification:

<web-app>
...

38 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<security-constraint>
<web-resource-collection>
<web-resource-name>SalesInfo</web-resource-name>
<url-pattern>/salesinfo/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
...
</web-app>

This security constraint authorizes users who are members of the manager group/role to
access sales information (information located in the /salesinfo directory, accessed
with either a GET or POST request). They must have logged on using a protocol that will
ensure the data is confidential (such as SSL). Any other kind of access to this resource
will be denied.

The role-name element can take the value "*" to indicate that all roles should be
included in this security constraint. The three allowable values for
transport-guaranteeare NONE, INTEGRAL and CONFIDENTIAL; the last two pretty
much require the use of SSL.

What if a user attempts to make a PUT request in the /salesinfo directory? That
would not be protected, although in this case, it presumably wouldn't be implemented.
Note that if you do not include the http-method tag, all request types are protected (a
handy default).

Here is the DTD for the security-constraint element and its children:

<!ELEMENT security-constraint (web-resource-collection+, auth-constraint?,


user-data-constraint?)>

<!ELEMENT web-resource-collection (web-resource-name, description?,


url-pattern*, http-method*)>

<!ELEMENT auth-constraint (description?, role-name*)>

39 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<!ELEMENT user-data-constraint (description?, transport-guarantee)>

! ( ' (#

This is the tag that declares how authentication will occur. Two examples are given: one
for basic authentication, one for form-based authentication; they require different tags:

<web-app>
...
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>manager</realm-name>
</login-config>
...
</web-app>

<web-app>
...
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/etc/login.jsp</form-login-page>
<form-error-page>/etc/login-error.jsp</form-error-page>
</form-login-config>
</login-config>
...
</web-app>

'#

This is a very simple declaration of a role:

<web-app>
...
<security-role>
<description>Corporate PHBs</description>
<role-name>manager</role-name>
</security-role>
...
</web-app>

40 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

. )

The authentication mechanism defined in HTTP 1.0. In response to a request for a


protected resource, a web server can send a request for authentication that includes a
domain. The user enters credentials (user name and password) for the indicated domain
and these are authenticated by the server before granting access to the resource. This
exchange occurs in the headers of the HTTP messages, and it is not secure: the
password is only Base 64 encoded and the server's identity is not verified.

DIGEST authentication is similar in most respects to BASIC authentication, except that


the password is encrypted, providing more security than BASIC authentication (but not
much more; it's considered trivial to break this encryption). As something of a halfway
measure, it hasn't fallen into widespread use.

Of the four authentication mechanisms, this one is specific to the servlet specification. It
defines cross-container support for a form-based login mechanism (where the user
enters a name and password in an HTML form). This type of authentication is no more
secure than BASIC authentication, but it provides a more flexible way to present the
login form to the user.

We've already seen how to declare the two relevant HTML pages in the deployment
descriptor. When a user attempts to access a restricted resource without being
authenticated, the login form will be returned instead. The login page must contain a
form with the following basic elements:

<form method="POST" action="j_security_check">


<input type="text" name="j_username"/>
<input type="password" name="j_password"/>
<input type="submit" value="Submit">
</form>

From the form's action, you can see that it is not dispatched via an URL to a page (JSP
or servlet). Instead, the servlet container intercepts the request and uses the
j_username and j_password values to attempt authentication. If the authentication is
successful and the user is authorized to access the requested resource, he or she is

41 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

directed to the page originally requested prior to authentication. Otherwise, the user is
directed to a 401 error page (either a page declared in the deployment descriptor or a
default page for the server).

) 0 1

CLIENT-CERT authentication is basically performed with HTTPS (are there any other
protocols? VPN maybe?). This is HTTP over an SSL connection, that uses public key
cryptography and digital certificates at both ends to authenticate the parties and secure
their communication. Such authentication can be considered secure (if the keys are
large).

& & & -

Identify which attribute scopes are thread-safe:


Local variables
Instance variables
Class variables
Request attributes
Session attributes
Context attributes
Multi-threaded and single-threaded servlets
SingeThreadModel Interface

+ %) - *

'

Yes. A different instance of each variable exists for each call to the method.

) '

No, since all the concurrent threads in a servlet's service method have access to the
servlet's instance variables. However, if you implement the SingleThreadModel
interface, the servlet's instance variables will be thread safe (either through
synchronization, or separate servlet instances).

42 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

No, not even if you implement the SingleThreadModel interface.

"# #

Basically no, because the request object is re-used between service requests and you
cannot hold a reference to a request object beyond the processing of the service
method, or pass a request object reference to another thread. At least, that's what the
spec says. I would say it is thread-safe because, why would you try and hold a reference
to the request object? And as long as you don't, you should be fine.

Obviously, my opinion counts for nothing on the exam.

No, multiple request threads can access it concurrently, and the SingleThreadModel
interface will not help here. Additional steps must be taken to synchronize access to
session attributes.

No, and duh. Many servlets could be accessing resources at the context level
concurrently; the programmer must synchronize such access.

- & -
The single-threaded servlet model is implemented by marking a servlet with the
SingleThreadModel interface.

In the single-threaded approach, the servlet container will create a separate servlet
instance for each request, or it may synchronize access to a single servlet instance. The
developer has no control over this, and each approach degrades performance over a
multi-threaded approach (either by consuming more memory, or by increasing the
response time to a request). Shared resources still pose synchronization problems, so
declaring this interface is kind of a joke--I speak from experience.

In the multi-threaded approach, the servlet container must instantiate one instance of the
servlet, and use it to process all requests (in separate threads). The performance is
superior, but the programmer must address concurrency issues in the code. If done
improperly, of course, your synchronization code could be as bad as synchronizing the

43 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

whole servlet.

& +
public interface javax.servlet.SingleThreadModel. It's a tag interface;
there are no methods.

& 1 2 &%

Write the opening and closing tags for the following JSP tag types:
Directive
Declaration
Scriptlet
Expression
Given a type of JSP tag, identify correct statements about its purpose or use.
Directives
Declarations
Scriptlets
Expressions
Given a JSP tag type, identify the equivalent XML-based tags.
Directives
Declarations
Scriptlets
Expressions
Identify the page directive attribute, and its values, that:
Import a Java class into the JSP page
Declare that a JSP page exists within a session
Declare that a JSP page uses an error page
Declare that a JSP page is an error page
Identify and put in sequence the following elements of the JSP page lifecycle:
Page translation
Match correct descriptions about purpose, function, or use with any of the following
implicit objects:
request
response
out

44 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

session
config
application
page
pageContext
Implicit object API
Scoped collections API
Dispatching methods
JspWriters
Error handling
exception
Distinguish correct and incorrect scriptlet code for:
A conditional statement
An iteration statement

& & & ) & &


% *

'

<%@ directive att="someValue" ... %>

'

<%! ... %>

'

<% ... %>

<%= ... %>

45 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

! % & %
'

'

The specification says directives are "messages to the JSP container." Among other
things, they indicate to the container how to translate a JSP source file into a servlet
source file. The following table summarizes the available directives:

Table 1. Directives

Attributes that apply to the page (and its includes) as a whole. Objective 8.4
page
discusses specific attributes for this directive (and there are many).
taglib declares a tag library that will be used in the page.
declares a file to be included verbatim at the position of the directive.
Basically a server-side include (the file could be a fragment). The file is
include treated as if it had been actually typed into the page. Contrast this with the
include action, where a request object is handed over to the included
resource, and the output of that processing is included into the final page.

'

Discussions of JSP are made more complicated by the fiction that JSP will be compiled
to some other language besides Java. Your JSP will be compiled into a Java servlet, and
a servlet is a class. In that class, declarations are the code that will be written in the
class, rather than in any particular method (particularly the service method and its
HTTP delegates). This can include variable declarations and initializations, or even
whole methods such as jspInit and jspDestroy. They should be complete code
fragments...they are written verbatim to the servlet class file.

All caveats about the thread safety of instance variables apply. Obviously, this code will
be available from other scriptlets or declarations on the page, which are part of the same
class.

'

Again, it's easiest to understand JSP if you think of how JSP elements are translated
into a servlet (although in practice, the actual servlet generated will include a lot of
additional code beyond what is specified by the developer in a JSP file).

Scriptlets define code fragments that appear in the service method of the servlet

46 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

generated from the JSP page (or whatever method service delegates to). They should
be complete language fragments, although they can be interspersed with the template
code that will be turned into println statements and spit out verbatim (as long as the
resulting mix is syntactically correct code). For example, the following is legal:

<% if (request.getAttribute("name") != null) { %>


<p>Hello <%= request.getAttribute("name") %> </p>
<% } else { %>
<p>Hello, World! </p>
<% } %>

Because it becomes something close to:

if (request.getAttribute("name") != null) {
out.println("<p>Hello " + request.getAttribute("name") + "</p>");
} else {
out.println("<p>Hello, world!</p>");
}

N.B. It's legal, but don't be surprised if your fellow team members strangle you for this
kind of code.

The content of an expression tag (which should be an expression) will be evaluated and
the result will be output as a String (with the toString method or some other
conversion routine for primitives). The expression is evaluated during request
processing, not during translation. If the result cannot be expressed as a String, this
will create a translation error or a runtime ClassCastException, depending on
whether the compiler can catch the error or not.

They are useful because they eliminate the need to use out.println in your JSP
page.

! & % % 0 6 5- & '

'

47 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<jsp:directive.page att="someValue" />


<jsp:directive.include file="someFile"/>

What about the taglib directive? It is nearly the equivalent of a namespace declaration
(except that unlike namespaces, the URI must be resolvable to an actual file, in this case
a TLD). Consequently, the taglib directive is subsumed by the root element of a JSP
page when it is expressed as XML:

<jsp:root
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:prefix1="URI-for-taglib1"
xmlns:prefix2="URI-for-taglib2"
version="1.2">
</jsp:root>

'

<jsp:declaration>
your declaration here
</jsp:declaration>

'

<jsp:scriptlet>
your scriptlet here.
</jsp:scriptlet>

<jsp:expression>
an expression here.
</jsp:expression>

+ % & *

) 2 ' ! 2 (

48 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<%@ page import="javax.sql.*, java.io.IOException" %>

The import list is comma separated, and it can include the wildcard character to import
an entire package. The following packages are imported without the need for a
declaration: java.lang*, javax.servlet.*, javax.servlet.http.*,
javax.servlet.jsp.*.

' ! 2 ( , !

<%@ page session="true" %>

If true, then the implicit variable session is available to scripts in the JSP page. If set
to false, this variable is not available (JSP developers should not circumvent this with a
call to HttpServletRequest.getSession).

' ! 2 ( # (

<%@ page errorPage="somePage.jsp" %>

If this page throws any Throwable (error or exception) at runtime, it will forward to the
indicated page and make the Throwable available on that page via the implicit
exception variable (it gets passed as a request attribute, but this doesn't particularly
matter). The response cannot have been committed. The JSP error page declared with
this directive will take precedence over any error file declared in the deployment
descriptor.

' ! 2 ( (

<%@ page isErrorPage="true" %>

If set to true, then an implicit exception variable is available that indicates the
Throwable thrown by the originating page. You can use this to log the exception and
display a message to the user.

+ % 0 ) &

49 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

& % *

Page translation - The JSP page is turned into a Java source file, representing a
class that implements a protocol-specific interface extending JspPage.

JSP page compilation - The JSP source file is compiled. This can occur any time
before the page first goes into service: during development, when the server
starts, the application is loaded, or the page is first requested. In Tomcat, the latter
strategy is used and there is a noticeable delay the first time the JSP page is
requested.

Load class - The class is loaded by the class loader... obviously when this occurs
depends a lot on when it is compiled.

Create instance - Probably created the first time it is requested, although with
servlets, you can load an instance and call init by specifying a
load-on-startup tag in the deployment descriptor.

Call jspInit - this method is called prior to the servicing of the first request; it can
be used to initialize the JSP page.

Call _jspService - this is the auto-generated method created by the JSP


translation engine that is used to service requests to the page.

Call jspDestroy - When the JSP page is taken out of service (e.g. in the process
of unloading a web application, or shutting down the server), this method is called
to enable the JSP page to perform clean up (releasing resources, writing state to
disk, etc.).

)
% ) & , *

"#

Basically it's the HttpServletRequest object available to servlets (since we assume


we're writing subclasses of HttpJspPage). It represents an HTTP request, including:

The HTTP headers;

50 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

information about where the request was directed;

the form parameters that were included with the request;

the cookies associated with the request;

a server-side session object associated with this user;

the user's security role (if authenticated);

a collection associated with the request, for the purpose of persisting objects for
processing by other components in the application.

It's the HttpServletResponse object available to servlets. It provides object-oriented


methods for generating the HTTP response, including:

methods and constants for setting the HTTP status code of the response;

methods for setting the content type and character encoding of the response;

methods for setting headers in the response;

a method for setting cookies in the response;

methods for generating redirections and sending errors to the user;

methods for retrieving a binary stream or text writer for outputting the HTTP
response body;

methods for manipulating the buffer associated with this stream or writer.

The response object buffer can be set with the JSP page directive. The buffer
attribute allows you to set the size of the buffer (e.g. "12kb", or the special value of
"none") while the autoFlush attribute specifies whether or not the buffer should be
flushed when it reaches it's maximum size (8kb or more by default). If set to "false", an
exception will be thrown if the buffer overflows. Auto flush can't be set to "false" if the
buffer is set to "none".

The out object is the JspWriter used to return output to the client. You cannot attempt
to get the PrintWriter or ServletOutputStream objects from a JSP page (these
are the servlet programmer's equivalent). The content type and encoding for the writer

51 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

can be set via attributes in the page directive (contentType and pageEncoding).

This is the HttpSession object available to servlet programmers. To get it manually


you would write something like:

HttpSession session = request.getSession(true);

The session object is valuable because it provides a collection for storing objects that
is associated with a particular user (actually, a particular web browser) that persists
between HTTP requests. In addition, it contains utility methods for examining the
session's creation and last access times, setting the timeout for the session, and
invalidating it.

' (

This is the ServletConfig object, which provides information about the parameters
that were set in the deployment descriptor for this servlet or JSP page. The parameters
allow deployers to alter the configuration of the application without altering servlets or
JSPs directly. It's other critical feature is the method getServletContext which
provides access to the ServletContext object. (in JSP, the equivalent of the
application implicit object).

'

This is the ServletContext object. It provides a number of useful features:

an application-level collection of objects available to all servlet/JSP components in


the application;

information about the servlet container (its name and version);

a method for accessing other servlet contexts on the server, and a


RequestDispatcher to dispatch requests across applications;

a facility for generating log files;

methods for accessing resources on the local filesystem, and to determine the
MIME type of those resources.

52 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

The page object is the javax.servlet.jsp.HttpJspPage object itself; in other


words, it is a reference to the object that the JSP page will be compiled into.

This is not typically used by JSP authors. You could, for example, use it this way:

<%= ((javax.servlet.jsp.HttpJspPage)page).getServletInfo()) %>

The cast to HttpJspPage is necessary because page is actually of type Object. It can
be any of a number of protocol-specific subclasses of JspPage (such as
HttpJspPage), so it must be downcast to the appropriate type.

This object provides convenience methods to JSP authors and some important
functionality to custom action developers (custom Tag classes acquire information about
page and application state through a reference to this object). The class provides:

an API for accessing the various implicit objects;

an API for manipulating the collections in all the implicit objects (across the page,
request, session and application-level scopes);

request dispatching methods;

a mechanism for getting the JspWriter associated with the page to output to the
response;

a method for handling exceptions and errors;

) ' + ' )

public java.lang.Object getPage();


public javax.servlet.ServletRequest getRequest();
public javax.servlet.ServletResponse getResponse();
public javax.servlet.jsp.JspWriter getOut();
public javax.servlet.http.HttpSession getSession();
public javax.servlet.ServletConfig getServletConfig();
public javax.servlet.ServletContext getServletContext();
public java.lang.Exception getException();

Not useful to JSP authors, but useful for custom action tag developers who acquire

53 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

access to these objects through the pageContext object.

' %' ' )

static int PAGE_SCOPE;


static int REQUEST_SCOPE;
static int SESSION_SCOPE;
static int APPLICATION_SCOPE;

public Object findAttribute( String key );


public int getAttributesScope( String key );
public void removeAttribute( String key );

public void setAttribute( String key, Object attribute );


public Object getAttribute( String key );

public Object getAttribute( String key, int SCOPE );


public void removeAttribute( String key, int SCOPE );
public java.util.Enumeration getAttributeNamesInScope( int SCOPE );

For action tag developers, these methods can be more convenient than operating on the
underlying objects and their collections. For JSP authors, these methods are not
particularly useful. Here's some rules about how this API behaves:

The find method searches the page, request, session and application
objects in that order, returning the first match. getAttributesScope behaves
the same way, but returns the scope constant for the scope in which it finds the
attribute.

the setAttribute and getAttribute methods that do not take a scope


constant operate on the page-level scope. But (rather confusingly) the
removeAttribute method that does not take a scope constant will search the
various scopes in the same way the findAttribute method does;

The methods that do take an int scope constant will all return null if the attribute
cannot be found in that scope.

'! ( ! %

54 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

public void forward( String relativeUrl )


throws ServletException, IOException;
public void include( String relativeUrl )
throws ServletException, IOException;

These should look familiar, they're similar to the request object's dispatching methods.
After a forward, you should not attempt to alter the response object for the page
(typically you don't do anything but return). When an include is used, the JspWriter is
flushed just before processing the include (which limits error-handling and header-setting
options at that point).

2 -

Particularly for custom action tag developers, it is necessary to acquire the writer being
used to output a JSP page.

! % (

handlePageException( Throwable t ), will hand off processing to the error page


for this JSP page (if there is one), or else perform some default error reporting for the
servlet container. After making this call you should not produce further output or modify
the response object.

'

Certain JSP pages can be designated error pages with the appropriate page directive
attribute. They catch exceptions or errors thrown by other pages; this Throwable is
made available on such error pages as the implicit exception object. With this object
available, you can undertake any error recovering or reporting you feel is prudent.

& *

' %

Here's a correct example of a conditional statement:

55 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<% if (request.getAttribute("name") != null) { %>


<p>Hello <%= request.getAttribute("name") %> </p>

<% } else { %>


<p>Hello, World! </p>
<% } %>

The key for objective 8.7 is to make sure everything is nested properly, and that all
necessary semicolons and braces are present in the right location (which can be difficult
to verify because of the JSP syntax).

Here's one potential way of writing an iterator (which purposefully jumps in and out of
code):

<ul>
<% for( Enumeration e = cards.elements(); e.hasMoreElements(); ) { %>
<li style="color: red; font-size: larger">
<%= ((Card)e.nextElement()).getName() %>
</li>
<% } %>
</ul>

The key for objective 8.7 is to make sure everything is nested properly, and that all
necessary semicolons and braces are present in the right location (which can be difficult
to verify because of the JSP syntax).

& & &/

Given a description of required functionality, identify the JSP page directive or


standard tag in the correct format with the correct attributes to specify the inclusion
of a Web component into the JSP page.
Includes
Forwards

! 0 % %

56 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

& & )
%
& '
JSP provides support for two kinds of includes and one kind of forward. Presumably all
three kinds of "inclusion" are covered by this section of the objectives.

) ' #%

The first kind of include is a page directive that acts exactly like a server-side include:
the include occurs during the translation of the page, and the included file is treated as if
it had been typed into the original page:

<@ include file="../inc/header.inc" %>

The second kind of include uses an action tag, and occurs at the time a request is
processed. This means that the request and response are processed by the included
resource and the output is included in the original file. The tag uses the request
dispatcher mechanism to fulfill the include, so the same rules apply: 1) the include is a
dynamic resource; 2) it can't set headers; but 3) the action tag will take a relative URL
(unlike the request dispatcher include method).

<jsp:include page="../errors/errorReport.jsp" flush="true"/>

/ , %

There is one standard forward method involving an action tag. It also uses the request
dispatcher forward method. It is executed at request time, and has the same rules as
the dispatcher method: 1) the response cannot have been committed; 2) existing output
at the time of the forward is cleared; and 3) you can set headers.

<jsp:forward page="../errors/errorReport.jsp"/>

Both of these action tags will accept nested param tags in order to set parameters for
the included or forwarded target (this also follows the RequestDispatcher's behavior).

57 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

The directive uses the attribute "file", while the action tags use
the attribute "page".

& & & & $ & 4

For any of the following tag functions, match the correctly constructed tag, with
attributes and values as appropriate, with the corresponding description of the
tag's functionality:
Declare the use of a JavaBean component within the page.
Specify, for jsp:useBean or jsp:getProperty tags, the name of an attribute.
Specify, for a jsp:useBean tag, the class of the attribute.
Specify, for a jsp:useBean tag, the scope of the attribute.
Access or mutate a property from a declared JavaBean
Specify, for a jsp:getProperty tag, the property of the attribute
JSP/servlet scoped attribute implementations
request scope
session scope
application scope
Identify techniques that access a declared JavaBean component

% ) & & %
& ) )
& & %*

' ! # 2 . ' , ! ! ( 3

Here's two examples based on the specification (the specification gives an example of
useBean without a scope attribute, yet it seems to require the scope attribute in the
formal definition of the tag):

<jsp:useBean id="userData" class="com.mycompany.UserData" >


<jsp:setProperty name="userData" property="type" value="webUser"/>
</jsp:useBean>

58 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<jsp:useBean id="connection" scope="session"


class="com.mycompany.DbConnection" type="java.sql.Connection"/>

In short, this tag attempts to find an existing object with a variable name equal to the id
in the specified scope; if it cannot, it will attempt to create a variable using these and
other attributes. It will place that variable in the appropriate scope and create a variable
for scripts on the page. If there are setProperty tags in the body of the useBean tag,
they will be used to initialize the bean's properties.

Table 1. Attributes

Attribute Rules Comment


Needs to be unique to the page and a valid variable
name. Identifies an object instance in a specified
scope, and also a scripting variable declared and
id required
initialized as a reference to that object (the same
thing and a fine point when the implementation
language is Java).
optional, default
scope Value can be page, request, session or application.
value is page
either class or type
must be present; do Fully qualified name of the class that implements this
class
not use beanName bean.
if you do use class
either class or type
The type of the variable to be created for the page
must be present;
(this might be a superclass or interface implemented
type OK to use
by the class). If used without the class or beanName
beanName if you
attributes, the object must already exist.
use type
The name of a Bean as expected by the
instantiate() method of the java.beans.Bean
use either class or
beanName class. Basically a fully-qualified class name or a
beanName
serialized bean. This attribute can accept a
request-time attribute value.

' * + 4# . + 4( ( * ! # 3

Apparently by convention rather than requirement, useBean declares a scoped

59 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

attribute/variable via its id attribute, while getProperty refers to that scoped


attribute/variable via its name attribute. In the example below, both of the tags appear on
a page in the following order:

<jsp:useBean id="someBean" scope="session" class="com.mycompany.ThisBean"/>


...
<jsp:getProperty name="someBean" property="someProperty"/>

In this case, a bean is being created/retrieved from the HttpSession object as


someBean, and later being referenced as such in order to output one of its properties to
the screen.

' * + 4# . (* ! ' ! # 3

<jsp:useBean id="userData" class="com.mycompany.UserData" >


<jsp:setProperty name="userData" property="type" value="webUser"/>
</jsp:useBean>

' * + 4# . (* ! ' ! # 3

The example again, this time with the scope attribute. The tag handler will first look for
the userData object in the session-level collection, then create it if necessary and store
it there. It also creates a variable with the name userData.

<jsp:useBean id="userData" class="com.mycompany.UserData"


scope="session">
<jsp:setProperty name="userData" property="type" value="webUser"/>
</jsp:useBean>

'' # % ' %2 .

The setProperty tag has several variations with different behavior (all the examples
below presume a bean has already been declared):

<jsp:setProperty name="myBean" property="someName" value="someValue" />

Sets the specific property of the bean to the indicated value, which can be a
request-time attribute value. In addition to setting the bean to any value, there is support
for setting bean properties based on servlet parameters:

60 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<jsp:setProperty name="myBean" property="someName" param="someParam" />


<jsp:setProperty name="myBean" property="someName" />
<jsp:setProperty name="myBean" property="*" />

The first version will set the property of the bean to the value of the (typically HTML
form) parameter specified by the param attribute. The conversion depends on the type
of the bean property (e.g. an integer value will be converted with Integer.parseInt).
You can use this form to map a parameter with a different name to the bean property.

The second version is a shorthand for cases where the parameter is named identically to
the bean property. You needn't specify the parameter in that situation.

The third version is an even more powerful shorthand that says, "search through the
form parameters, and any time you have a parameter named after a bean property, use
it to set the bean property."

You cannot use both the param and value attributes in the same setProperty tags.

' * + 4( (* ! ! #

<jsp:getProperty name="someBean" property="userType"/>

This tag retrieves the value of the specified property, converts it to a string (via the
toString method), and outputs it to the page (again we are assuming the bean has
already been declared with the useBean tag).

"# '

This refers to the HttpServletRequest object and its interface for manipulating a
collection of associated attributes.

'

This refers to the HttpSession object and its interface for manipulating a collection of
associated attributes.

' '

61 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

This refers to the ServletContext object and its interface for manipulating a collection
of associated attributes (context is the servlet word that combines application and
server-level functionality).

+ % 0 4
This has been covered elsewhere in section 10; the outstanding thing to note is that a
declared JavaBean component can also be accessed via script (as well as the JavaBean
action tags). For example:

<jsp:useBean id="userBean" scope="session"


type="com.mycompany.Profile"/>
...
<%= userBean.getFirstName() %>
<jsp:getProperty name="userBean" property="firstName"/>

Once the bean is declared, the last two lines perform equivalent tasks.

& & & & $ & &

Taglibs in the deployment descriptor


Taglib directives
Given a custom tag library, identify properly formatted custom tag usage in a JSP
page. Uses include:
An empty custom tag
A custom tag with attributes
A custom tag that surrounds other JSP code
Nested custom tags

& %
The deployment descriptor maps an URI to an actual TLD file, allowing you to use the
URI in the JSP taglib directive. Later if you need to move the TLD or rename files, this
mapping allows you to do so without editing a large number of JSP pages.

62 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<web-app>
...
<taglib>
<taglib-uri>/myTagLib</taglib-uri>
<taglib-location>/WEB-INF/tlds/myTagLib.tld</taglib-location>
</taglib>
...
</web-app>

The example covers all possibilities described by the DTD schema for this element:

<!ELEMENT taglib (taglib-uri, taglib-location)>

&

<%@ taglib uri="/WEB-INF/tlds/myTagLib.tld" prefix="mtl"%>


<%@ taglib uri="/myTagLib" prefix="mtl"%>

The URI given can either be an absolute path to a TLD file, from the root of the web
application context, or it can be mapped to a TLD file in the deployment descriptor. Later
in the page, the defined prefix can be used as the namespace for tags from this library.

! & % % %
& & & '$ *

'# (

If we declared a custom tag library and gave it a prefix of alx, an empty tag with no
attributes would look like this:

<alx:doIt/>

This is also legal:

63 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<alx:doIt></alx:doIt>

'# (, ! #

Assuming we've declared the use of a tag library with the prefix of alx, it should look
like one of these two tags:

<alx:doIt repeat="10"/>
<alx:doIt repeat="10"></alx:doIt>

'# ( ! # # % ! 2 ' %

The only issue here would be proper nesting of the tags. Again assuming a tag library
with a prefix of alx:

<ul>
<alx:doIt repeat="10">
<li><jsp:getProperty name="someBean" property="nextUser"/></li>
</alx:doIt>
</ul>

0 % '# (

As the objective says, the main issue is just getting the tags nested properly. Whether a
pair of nested custom tags interact with one another depends entirely on their
implementation:

<ul>
<alx:doIt pageLimit="10">
<li><alx:nextUser bean="someBean"/></li>
</alx:doIt>
</ul>

& & & &5 %

Identify the tag library descriptor element names that declare the following:

64 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

The name of the tag


The class of the tag handler
The type of content that the tag accepts
Any attributes of the tag
Identify the tag library descriptor element names that declare the following:
The name of a tag attribute
Whether a tag attribute is required
Whether or not the attribute's value can be dynamically specified
Given a custom tag, identify the necessary value for the bodycontent TLD element
for any of the following tag types:
Empty-tag
Custom tag that surrounds other JSP code
Custom tag that surrounds content that is used only by the tag handler
Given a tag event method (doStartTag, doAfterBody, and doEndTag), identify the
correct description of the methods trigger
doStartTag
doAfterBody
doEndTag
Identify valid return values for the following methods:
doStartTag, doAfterBody, doEndTag, PageContext.getOut
Given a BODY or PAGE constant, identify a correct description of the constant's
use in the following methods:
doStartTag
doAfterBody
doEndTag
Identify the method in the custom tag handler that accesses:
A given JSP page's implicit variable
Nested tags

I have found the following tables helpful in learning aspects of custom action
programming that are difficult for me to remember. One of my measurements of a
successful software design is its memorability, and by this measure, the
javax.servlet.jsp.tagext package is kind of a mess.

The first table shows, for several different types of tag, the interface or class you would
use to create such a tag, and the methods and sequence of calls that would be made on
that tag handler class. It is based on a table in the J2EE 1.3 tutorial on custom tags,
although I have expanded it:

Table 1. Classes and Methods Required by Kind of Tag

65 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Method Call
Type Explanation Interface Implementation
Sequence
Contains no doStartTag,
Simple body and no Tag TagSupport doEndTag,
attributes. release
setAttribute
Contains no (1..n),
Attributes body, but has Tag TagSupport doStartTag,
attributes. doEndTag,
release
Contains body
content that is doStartTag,
Body, no
either skipped or Tag TagSupport doEndTag,
interaction
evaluated by release
JSP container.
Contains body
doStartTag,
Iterative content passed
doAfterBody,
tag, no to JSP engine for IterationTag TagSupport
doEndTag,
interaction evaluation one or
release
more times.
Contains a body doStartTag,
that is processed doInitBody,
Body,
one or more BodyTag BodyTagSupport doAfterBody,
interaction
times by the tag doEndTag,
handler. release

+ % & %
) &*

! ! (

The tag library descriptor file has changed in many minor ways
between version 1.1 and 1.2. It would be easy on the test to
remember the old version of a tag, rather than the newer
version. Here's an entire entry in the TLD file (minus a

66 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

declaration for a scripting variable) with the name declaration in


bold:

<taglib>
...
<tag>
<name>crazyFont</name>
<tag-class>us.alxdark.tags.CrazyFont</tag-class>
<tei-class>us.alxdark.tags.CrazyFontTEI</tei-class>
<body-content>JSP</body-content>
<display-name>Crazy Font</display-name>
<attribute>
<name>bgcolor</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>The background color as commonly expressed in
web design: #FFFFFF. Crazy Font will avoid selecting a random
color that comes too close to the background color. </description>
</attribute>
</tag>
<taglib>

Here is the DTD for this tag, which I won't repeat in later sections:

<!ELEMENT tag (name, tag-class, tei-class?, body-content?,


display-name?, small-icon?, large-icon?, description?, variable*,
attribute*, example?)>

! ' ! (! %

<taglib>
...
<tag>
<name>crazyFont</name>
<tag-class>us.alxdark.tags.CrazyFont</tag-class>
<tei-class>us.alxdark.tags.CrazyFontTEI</tei-class>
<body-content>JSP</body-content>
<display-name>Crazy Font</display-name>
<attribute>
<name>bgcolor</name>

67 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>The background color as commonly expressed in
web design: #FFFFFF. Crazy Font will avoid selecting a random
color that comes too close to the background color. </description>
</attribute>
</tag>
<taglib>

! ' ! ! ( ''

<taglib>
...
<tag>
<name>crazyFont</name>
<tag-class>us.alxdark.tags.CrazyFont</tag-class>
<tei-class>us.alxdark.tags.CrazyFontTEI</tei-class>
<body-content>JSP</body-content>
<display-name>Crazy Font</display-name>
<attribute>
<name>bgcolor</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>The background color as commonly expressed in
web design: #FFFFFF. Crazy Font will avoid selecting a random
color that comes too close to the background color. </description>
</attribute>
</tag>
<taglib>

Table 2. Body Content Values

Label Comment
"The body of the tag is interpreted by the tag implementation itself, and
tagdependent is most likely in a different 'language', e.g. embedded SQL statements."
(JSP 1.2 spec)
The default value if this tag is not included. "The body of the tag
JSP contains nested JSP syntax." (JSP 1.2 spec). It can be nothing but
template (HTML) text.
empty "The body must be empty" (JSP 1.2 spec).

68 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

# ! (

<taglib>
...
<tag>
<name>crazyFont</name>
<tag-class>us.alxdark.tags.CrazyFont</tag-class>
<tei-class>us.alxdark.tags.CrazyFontTEI</tei-class>
<body-content>JSP</body-content>
<display-name>Crazy Font</display-name>
<small-icon>images/cfont-small.png</small-icon>
<large-icon>images/cfont-large.png</large-icon>
<description>A sample tag.</description>
<attribute>
<name>bgcolor</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>The background color as commonly expressed in
web design: #FFFFFF. Crazy Font will avoid selecting a random
color that comes too close to the background color. </description>
</attribute>
<example>
This is an example for a human viewer of the file. Optional.
<alx:crazyFont bgcolor="#FFFFFF">Wacka wacka!</alx:crazyFont>
</example>
</tag>
<taglib>

+ % & %
) &*

! ( #

<taglib>
...
<tag>
...
<attribute>
<name>bgcolor</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>

69 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

<description>The background color as commonly expressed in


web design: #FFFFFF. Crazy Font will avoid selecting a random
color that comes too close to the background color. </description>
</attribute>
</tag>
<taglib>

The name tag indicates the name of the attribute.

<!ELEMENT attribute (name, required?, rtexprvalue?, type?, description?)>

-! ! ( # "# %

<taglib>
...
<tag>
...
<attribute>
<name>bgcolor</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>
</tag>
<taglib>

required indicates whether or not the attribute must be present. If the attribute is not
required, the tag handler will have to supply a default value.

-! ! ! # 5 # ' % ' ' %

<taglib>
...
<tag>
...
<attribute>
<name>bgcolor</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>

70 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

</tag>
<taglib>

rtexprvalue indicates whether or not the value can be supplied by a request-time


attribute (as opposed to a statically defined value). If the value must be specified
statically, then the type of the attribute will always be a String. If the value is indicated at
request time, however, it will be an expression that may return any Java type, so the
type tag should be used in conjunction with this declaration to indicate the type of the
return value.

! & % %
% 5 % ) & & % *

1 (

Note that they wrote bodycontent (JSP 1.1) but it should presumably be
body-content (JSP 1.2).

The value is "empty".

# ( ! # # % ! 2 ' %

The value is "JSP".

# ( ! # # % ' ! # % ! (! %

The value is "tagdependent".

! & 1 & ( 4 %
" &2 %
&&

% (

It is triggered after the event handler is initialized and attributes are used to set
properties on the tag handler object. It happens before any body-related methods are
called, and thus corresponds to the end of the initial start tag of the action.

71 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

% . %

If the body is not skipped, but passed through for evaluation, then this method will be
called after the body is evaluated, but before the doEndTag method. Depending on the
return code returned by doAfterBody, the body of the tag may be evaluated again.

For this method to be part of a tag handler, it must implement either the IterationTag
or BodyTag interface.

% % (

This tag is called last in the handling of the action, and corresponds to the end tag for
the action. It is always called, whether or not the body of the tag is empty and whether or
not it is evaluated.

+ % ) & *

% (* % . % *% % (* ( 3( #

These return codes determine the order in which these methods are called, in ways
particular to each of the three tag interfaces. The valid return codes are summarized for
each of the interfaces below:

Table 3. Tag Interface Lifecycle

Method Constant Meaning


If the TLD specifies in a body-content
tag that the tag is empty, then
Tag.SKIP_BODY
doStartTagmust return this value.
doStartTag
Proceed to doEndTag.
Body is evaluated and passed through to
Tag.EVAL_BODY_INCLUDE
current out.
Tag.EVAL_PAGE Evaluate the rest of the page, as normal.
doEndTag Stop processing the page (e.g. error or
Tag.SKIP_PAGE
forwarding situation).

Table 4. IterationTag Interface Lifecycle

72 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Method Constant Meaning


If the TLD specifies in a
body-content tag that the tag
Tag.SKIP_BODY is empty, then
doStartTag doStartTagmust return this
value. Proceed to doEndTag.
Body is evaluated and passed
Tag.EVAL_BODY_INCLUDE
through to current out.
IterationTag.EVAL_BODY_AGAIN Evaluate the body again.
Do not evaluate body again. If
you want to skip evaluation of
doAfterBody
Tag.SKIP_BODY body entirely, this value must be
returned from doStartTag.
Proceed to doEndTag.
Evaluate the rest of the page, as
Tag.EVAL_PAGE
normal.
doEndTag
Stop processing the page (e.g.
Tag.SKIP_PAGE
error or forwarding situation).

Table 5. BodyTag Interface Lifecycle

Method Constant Meaning


If the TLD specifies in a
body-content tag that the tag
Tag.SKIP_BODY is empty, then
doStartTagmust return this
value. Proceed to doEndTag.
doStartTag Body is evaluated and passed
Tag.EVAL_BODY_INCLUDE
through to current out.
Creates a BodyContent object
that captures the processing of
BodyTag.EVAL_BODY_BUFFERED
the body, for manipulation by the
tag handler.
This method is only called on
tags that implement BodyTag
doInitBody
and that return
EVAL_BODY_BUFFERED from

73 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

Method Constant Meaning


their doStartTag method.
IterationTag.EVAL_BODY_AGAIN Evaluate the body again.
Do not evaluate body again. If
you want to skip evaluation of
doAfterBody
Tag.SKIP_BODY body entirely, this value must be
returned from doStartTag.
Proceed to doEndTag.
Evaluate the rest of the page, as
Tag.EVAL_PAGE
normal.
doEndTag
Stop processing the page (e.g.
Tag.SKIP_PAGE
error or forwarding situation).

PageContext.getOut returns a JspWriter, although this is not the full story. When
this method is called by a BodyTag handler, or it is called by a nested tag handler, the
actual object may be an instance of BodyContent, which has methods for accessing
the body content after it has been processed.

! BODY PAGE %
) & *
doStartTag

SKIP_BODY

For custom actions based on the Tag or IterationTag interfaces, using the
SKIP_BODY constant as a return value indicates that the body content should be
skipped over (this should also be indicated in the tag's TLD body-content tag).
The next method called will be doEndTag (the IterationTag will not have its
doAfterBody method called).

EVAL_BODY_INCLUDE

The value EVAL_BODY_INCLUDE indicates that the body should be evaluated, as


normal.

EVAL_BODY_BUFFERED

74 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

The BodyTag interface can legally return one more constant value,
EVAL_BODY_BUFFERED, which creates a BodyContent object to be processed
by the tag itself in the doInitBody and doAfterBody methods. In those
methods, the implicit object out will write to this BodyContent object.

% . %

EVAL_BODY_AGAIN

EVAL_BODY_AGAIN indicates that the body should be evaluated again, and


provides a mechanism to iterate over the contents of the body during processing
(e.g. to generate new content based on a nested action tag).

SKIP_BODY

Two valid return constants exist for the doAfterBody method. SKIP_BODY
indicates that processing should stop and continue to doEndTag.

% % (

EVAL_PAGE

EVAL_PAGE indicates that processing should through the rest of the page.

SKIP_PAGE

SKIP_PAGE indicates that processing should come to an end, and the rest of the
page should be ignored. I can't think of why you'd use the second method, unless,
you were forwarding or reporting an error.

+ % & *

( 2 ( 5 '

Essentially all of the variables that define a JSP page's state are accessible through the
PageContext object, which is stored as a protected data member, pageContext, in
the TagSupport and BodyTagSupport implementation classes.

8 &

75 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

A tag handler will implement the Tag.getParent method, which returns the
immediately enclosing outer tag. If you are not sure at what level the outer tag will be
located relative to the inner tag, there is a static method on the implementing class,
TagSupport, to search up the containment hierarchy until a tag handler of the correct
class is found:

public class TagSupport {


static Tag findAncestorWithClass(Tag from, java.lang.Class klass);
}

An example use of this method (from JavaServer Pages, Bergsten, O'Reilly 2001):

Tag parent = findAncestorWithClass( this, ParamParent.class );

If this example did not find an outer tag handler of the class ParamParent, it would
return null.

&

Given a scenario description with a list of issues, select the design pattern that
would best solve those issues
Value Object
MVC
Data Access Object
Business Delegate
Match design patterns with statements describing potential benefits that accrue
from the use of the pattern, for any of the following patterns:
Value Objects
MVC
Data Access Object
Business Delegate

! )
& )

76 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

In this section I provide a brief description of each design pattern, and then enumerate
their benefits in the next section. You'll have to determine a particular pattern addresses
an issue or problem described in the exam.

6 # + '

Some entity objects have attributes that are always used together, such as a postal
address or a user's preferences. In an RMI-based application (like a J2EE application
using Enterprise JavaBeans), every access of an attribute involves a remote procedure
call over the network (getStreet, getCity, getPostalCode, etc.), leading to
significant network traffic and EJB resource usage. The solution is to bundle this
information into a class known as a "value object". This object has properties for all
these attributes and it is returned by a single RMI call. It can then be accessed locally to
retrieve the required attributes.

A value object represents the attributes but not the operations of a remote enterprise
business component, so it can be used locally, but it will need to be passed back
(modified) in the course of executing remote business logic.

Use value objects whenever you are passing sets of attributes in an RMI context,
particularly if these attributes are used together in different places in the application.

The Model-View-Controller architecture is a well-established paradigm for building user


interfaces that has been applied with success to the architecture of web applications. In
this model, the presentation tier involves three components: 1) the model; 2) the view;
and 3) the controller. The model represents the state of the application and its business
logic; the view displays the current state to the user; and the controller intermediates
between these two components, translating user interface events into semantic
operations on the model, and possibly updating the view to reflect changes in the model
(although the model may also send events to the view to keep these two components
synchronized). In the world of J2EE development, a particular application might choose
use JSP for the views, servlets and delegate classes for the controllers, and EJBs to
maintain the application model.

The MVC architecture provides two specific benefits (they're actually the same benefit,
seen from two different angles). First, it is possible to provide multiple views of the same
application. Swing uses this approach to provide multiple "look-and-feels" on top of its
toolkit, while a web application might use this architectural advantage to output different
markup (e.g. for desktop PCs and mobile phones). On the other hand, the model is
isolated from its manipulation by a particular user interface, so the application model can

77 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

be re-used or used in multiple user interfaces, e.g. a web application and a Swing client
program.

Use the MVC model, period. Seriously, use MVC if the application will need to support
different clients or the business logic of the application could be reused in other
contexts. In today's world (where service-based architectures are becoming a common
response to the Internet), this describes most non-trivial applications.

'' + '

Many business components representing business entities store their state in an


underlying data source, such as a relational database or XML file. Unfortunately, access
to these stores is often not standardized (SQL dialects being a prime example here).
How do you create an application that can inter-operate with different data sources
without rewriting major portions of the application?

To isolate such changes, business components can interact with data sources through
the data access object pattern. An interface provides an abstract set of methods for
storing/updating/saving the data, while the actual access code is delegated to sets of
DAO implementation classes that handle the specifics of the data access. When the
application is deployed, the right set of DAO implementation classes can be selected for
the environment. Changes to the application, or to the data storage of the application,
remain isolated from one another. Supporting a new data source only requires adding a
new data access implementation component for each business component.

In any event, that's what Sun's design patterns documentation


says. Adding new DAO implementations for every entity in your
application can be a pain. Think about using a data binding
technology like Castor instead.

Use DAOs when you want to separate business logic from data access logic; support a
particular data source dynamically at deployment or runtime; or remove the impact of
changing a data source on other components in an application.

.# (

In a J2EE application, the client will often interact directly with business components via
RMI. There are a couple of negative consequences: RMI code is subject to change if the
business components change, and the client must deal manually with caching resources

78 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

(e.g. a stable list of business locations). Both of these complexities can be hidden behind
a client-side business delegate layer. The components in this layer provide an API for
client-side code, while encapsulating the RMI and caching code that can change as a
result of changes in other business components.

& ) &
%
) & *

6 # + '

Improves network traffic and response time;

Reduces the load on enterprise beans.

Allows multiple views using the same model

Eases support for new types of clients

'' + '

Greater deployment flexibility

Independence from specific vendor APIs

Independence from a specific type of data source (e.g. database, XML file)

Application can be easily extended with support for new data sources

.# (

Reduces coupling of client and business tiers, improving manageability;

Can translate network/infrastructure exceptions into business exceptions;

Provides a client friendly, potentially simplified interface;

May improve performance by providing caching.

79 of 80
Sun's Java 2 Web Component Developer Certification http://home.earthlink.net/~alxdark/software/wcd-guide/wcd-guide.html

None of these excellent sources can be blamed for mistakes in this text--they are my
own. Please let me know about them.

Java Servlet Specification 2.3. Sun Microsystems 2001.

JavaServer Pages. Bergsten, Hans. O'Reilly 2002.

JavaServer Pages Specification 1.2. Sun Microsystems 2001.

Sun Certified Web Component Developer Study Guide. Ken Zrobok, 2001?

Web Development with JavaServer Pages. Fields, Duane and Mark Kolb. Manning,
2000.

80 of 80

Das könnte Ihnen auch gefallen