Sie sind auf Seite 1von 25

Head First Servlets and JSP - Errata

by Bryan Basham, Kathy Sierra, Bert Bates

This errata page lists errors outstanding in the most recent printing.

If you have technical questions or error reports, you can send them to
booktech@oreilly.com. Please specify the printing date of your copy.

This page was updated March 1, 2007.

Here's a key to the markup:


[page-number]: serious technical mistake
{page-number}: minor technical mistake
<page-number>: important language/formatting problem
(page-number): language change or minor formatting problem
?page-number?: reader question or request for clarification

Confirmed errors:

{xxvi} 2nd bullet point;


http://jakarta.apache.org/site/bin/index.cgi
SHOULD BE
http://jakarta.apache.org/site/binindex.cgi

(6) bottom of page;


(FYI: HTTP stands for HyperText Transport Protocol.)
should read
(FYI: HTTP stands for HyperText Transfer Protocol.)

(15) Request line description;


There is a discrepancy between the request line description in the middle of the page:
GET /select/selectBeerTaste.jsp
and in the "cloud callout" of the web browser at the bottom left of the page:
/select/selectBeerTaste.html
it should say:
/select/selectBeerTaste.jsp

(21) 2nd para - last sentence;


The last sentence reads...

And even if it did, the POP3 server doesn't known anything....


it should be:
And even if it did, the POP3 server doesn't know anything....

(26) 1st paragraph - line 3;


"exist before the request). and the ..."
should be
"exist before the request) and the ..."

[30] the first line of web.xml;


the first line of the web.xml file should be:
<?xml version="1.0" encoding="ISO-8859-1"?>

[30] Step 3 - within the xml code for the DD;


the third and fourth lines of xml read:

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
web-app_2_4.xsd"

This should be combined into one line, and a forward slash


should be inserted between the "j2ee" and the "web-app_2_4.xsd":

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"

(35) 2nd bullet point;


"... server gives back and HTTP response..."
should be:
"... server gives back an HTTP response..."

(48) second paragraph to the last on the bottom;


This is the what the client...
should be:
This is what the client...

(58) First bullet point, last sentence;


The text ends with
"so that you can concentrate of your own business logic".
it should be:
"so that you can concentrate on your own business logic".
{58} 3rd bullet point;
The 3rd bullet point reads...
"A typical servlet is a class that extends HttpServletRequest"
should be:
"A typical servlet is a class that extends HttpServlet"

[62]
The 4th hand-written note "Gets the response from the container"
should read "Container generates the HTTP response stream from
the data in the response object" in the column marked "Container"

(65) 1st paragraph;


"it incorporates other specifcations,..."
should be
"it incorporates other specifications,..."

{71} Figure edit (per author):


In the top figure, labeled "Web Server," move the form.html file into the Container box.

(77) 2rd paragraph;


and save it in your deployment environment under ....
should be
and save it in your development environment under ....

(78) handwritten comment;


...to the URL of the page its on.
should be:
...to the URL of the page it's on.

{82} 2nd paragraph;


- Its directory structure should be /WEB-INF/classes/com/model
should have been
- Its directory structure should be /WEB-INF/classes/com/example/model

{84} Addition of new code ;


The code for servlet version three on page 89 shows the following line as commented
out:
// out.println("<br>Got beer color " + c);

However, that line never appeared in the servlet version two code and should be added
(uncommented out and in bold) just above the following line on page 84:
BeerExpert be = new BeerExpert();

AUTHOR:
This is how I would reorganize these two code examples in a
future printing of the book.

First, on pg 84 move all of the code that (a) retrieves the


'color' parameter and (b) retrieve the results of the beer
search from the BeerExpert to the top of the doPost method.
Put the code to (a) set content type, (b) retrieve the Writer,
and (c) generate the response at the bottom of the doPost
method.

Second, on pg 89, reproduce the code structure from above,


but now comment out the bottom half which is being replaced
by the code to (a) set the 'styles' attribute, (b) create the
RequestDispatcher, and (c) forward to the view ReqDisp.

(90) first sentence following "Deploying and testing the web app";
"redploy"
should be:
"redeploy"

(90) Last picture at bottom of page;


try: Jack's Pale Ale
should read:
try: Jail Pale Ale

(94) Coverage notes, 4th paragraph;


"because the questions requires additional knowledge"
Should read:
"because the questions require additional knowledge"

{100} Thought bubble at top left.;


The final sentence says:

"So each time my doGet() or doPost() runs, it's in a separate method"


SHOULD READ

"So each time my doGet() or doPost() runs, it's in a separate thread."

{106} ServletResponse interface;


ServletResponse Interface shown has two setContentType() methods.
One of them should be getContentType()

{106} ServletRequest interface;


The line:
"getParameter()"
should be:
"getParameter(String)"

(114), the answer to the "Sharpen your pencil" exercise


"The HTTP 1.1 spec declares GET, HEAD, and PUT as idempotent, even
though you CAN write a non-idemptotent doGet() method

should be:
"The HTTP 1.1 spec declares GET, HEAD, and PUT as idempotent, even
though you CAN write a non-idempotent doGet() method

the term "non-idemptotent" should read "non-idempotent"

{114,116} Answer to Sharpen your pencil at bottom of page 114;


"POST is considered idempotent by the HTTP 1.1 spec."
should be:
"POST is not considered idempotent by the HTTP 1.1 spec."

(118) last paragraph (prefixed with "A:");


The "...if this request doesn't need to do post things..." wording is confusing given
the question is in regards to supporting *both* GET and POST.

Suggesting rewording: "A: Developers who want to support both methods usually put
logic in doGet(), and then have the doPost() implementation delegate to that doGet():"

{123} 2nd paragraph;


The Input stream from request.getInputStream() will only
contain the body, not the header
(132) Last Paragraph;
Information at the bottom of the page labeled 'fiy' should be 'FYI'

[136] 3 changes on this page;


Third hand-written note from the top should read:
The forward slash at the beginning means "relative to the root of the web container."

The last paragraph (and code) should read:


The Container builds the complete URL relative to the web container itself, instead
of relative to the original URL of the request. So the new URL will be:
http://www.wickedlysmart.com/foo/stuff.html

Fourth hand-written note from the top should read: See... the
"myApp/cool" part of the path isn't here this time.

{154} TestInitParams source code;


The source code for the TestInitParams servlet is missing an import.
Add:
import java.util.*;

Without the import the code won't compile because the Enumeration class is used.

[154] the first line of web.xml;


the first line of the web.xml file should be:
<?xml version="1.0" encoding="ISO-8859-1"?>

(158) in the deployment descriptor section;


<servlet-name>
BeerParamTests
<servlet-name>

it should be like this:

<servlet-name>
BeerParamTests
</servlet-name>

{162} ServletContext interface;


"setAttribute(String)"
should read:
"setAttribute(String, Object)"

(177) Last line;


URL pattern mapped to this the servlet: ListenTest.do
should read:
URL pattern mapped to the servlet: ListenTest.do

(182) "Scenario" column, 5th row of grid;


"will stored " should be "will be stored "

{189} top right paragraph;


enumeration getAttributeNames()
should be:
Enumeration getAttributeNames()

{189} ServletRequest interface box;


ServletRequest interface box shows method name of getContextType(), where it should
be getContentType().

{189} HttpSession interface Column;


In the list of methods for HttpSession Interface, the
setMaxInactiveInterval is shown without arguments.
setMaxInactiveInterval() should instead be written as
setMaxInactiveInterval(int interval)

(199) 2nd paragraph;


'Are they are safe?'
should be:
'Are they safe?'

{200} 7th line of code;


out.println("test context attributes<br>");
should be:
out.println("test session attributes<br>");

(206) second column 5th row;


Lifecycle event related to ServletRequest:
Method:
SessionDestroyed() should be requestDestroyed()

{211, 217} 1st paragraph;


Which statements about listeners defined in the javax.servlet package are true?
should be:
"Which statements about listeners are true?"

[213] Q 12 - item D;
ServletRequest
should be:
HttpServletRequest

(213) Question 12, answer E;


In the last option (E) of question 12, the test states: 'The servlet to which a
request is forwarded may access the original query string by calling
getAttribute("javax.servlet.forward.query_string") on the' This statement is not
finished on the next line or the next page.

"ServletRequest" should be added to the last sentence of option E.

[215] Answer to question 1;


Option C should also be checked.

[214 + 220] Q 13;


this option is worded poorly. I would rephrase it as:
"If the servlet implements javax.servlet.SingleThreadModel,
the container may use one instance for each simultaneous
request."

[219] Q12 Answer D;


Answers D and E are checked, but only E should be.
getQueryString() returns the dispatcher request path's query string, not the original query
string.
(231) 2nd handwritten paragraph from the top starting with "(This method..." - 2nd
sentence starting wih "Now, there's still...";
"Now, there's still not guarantee the client will ACCEPT the cookie..."
should read:
"Now, there's still no guarantee the client will ACCEPT the cookie..."

(235) diagram of HTTP response;


the closing angle bracket for the anchor tag 'a href="http://wick.."' is missing

{238} point 4 on the Bullet Poins;


out.println("<a href=\"" +
response.encodeURL("/BeerTest.do"));

should be read:

out.println("<a href=\"" +
response.encodeURL("/BeerTest.do") +
"\">Click Me</a>");

(242) second column, fifth row;


the parenthetical expression reads:
(for example, after the client does a shopping check-out or logs).
it should be
(for example, after the client does a shopping check-out or logs out)

{245} Example 2;
delete the line:
String foo = (String) session.getAttribute("foo");

out.println("Foo: " + foo);


should read:
out.println("Foo: " + session.getAttribute("foo"));

{251} source code;


There should be a

if (cookies!=null) {
}

after
Cookie[] cookies = request.getCookies();

[254] Standout titled "You do NOT configure session binding listeners in the DD!;
Standout reads:

"You do NOT configure session binding listeners in the DD! ... But this is NOT true
for the other session related listeners on the previous page. HttpSessionListener,
HttpSessionAttributeListener, and HttpSessionActivationListener must be registered
in the DD, since they're related to the session itself, rather than an individual
attribute placed in the session."

Should read:

""You do NOT configure session binding listeners OR SESSION ACTIVATION


LISTENERS in
the DD! ... But this is NOT true for the other session related listeners on the
previous page. HttpSessionListener and HttpSessionAttributeListener must be
registered in the DD, since they're related to the session itself, rather than an
individual attribute placed in the session."

{258} Serialization box at bottom of page;


"...can also choose to implement a readObject() method, called by the VM whenever an
object is serialized, and a writeObject() method, called when an object is deserialized."

Should read:

"...can also choose to implement a writeObject() method called by the VM whenever an


object is serialized, and a readObject() method, called when an object is deserialized."

{261} Bang box:


The Bang! box on pg 261 is erroneous and should be dropped altogther.

(262) 2nd column, 4th row;


HttpSessionAtrributeListener should be HttpSessionAttributeListener

(265 and 272)Question 1:


public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws IOException, ServletException {
// request.getSession().setAttribute("key", "value");
// request.getHttpSession().setAttribute("key", "value");
// ((HttpSession)request.getSession()).setAttribute("key", "value");
// ((HttpSession)request.getHttpSession()).setAttribute("key", "value");
}
}
Should be:

public class MyServlet extends HttpServlet {


public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws IOException, ServletException {
// req.getSession().setAttribute("key", "value");
// req.getHttpSession().setAttribute("key", "value");
// ((HttpSession)req.getSession()).setAttribute("key", "value");
// ((HttpSession)req.getHttpSession()).setAttribute("key", "value");
}
}

change "request" to "req" to make it consistent!

{274} Q7, Answer C;


Answer C left off a vital part of the sentence when it was copied from the Servlet
specification.
The Servlet specification says:

'Any object bound into a session is available to any other servlet that belongs to
the same ServletContext and handles a request identified as being a part of the same
session.'

Answer C leaves off the final part of the sentence: 'and handles a request identified
as being a part of the same session.' Without this answer C is not correct.

[276] Question 12, Option C;


Rewrite item C as: "When a session is moved from one JVM to another,
objects within the session that implement HttpSessionActivationListener
will be notified."

(287) black box at bottom;


AS IS:
<%= becauseThisIsAnArgumentToWrite() %>

SHOULD BE:
<%= becauseThisIsAnArgumentToPrint() %>

WHY THIS IS IMPORTANT:


There is also an error on page 343, which gets out.print() and out.write() mixed up.
Combined, these two errors confuse this point: JSP expressions become out.print() in
the _jspService() method and plain old template text becomes out.write() in the
_jspService() method.

(288) 6th 'sharpen your pencil' question;


<%= newString[3]) %>
should be:
<%= newString[3] %>

(288) 7th 'sharpen your pencil' question;


<% = 42*20; %>
should be:
<% = 42*20 %>

(293), in both of the code snippets,


... extends HttpServlet {

is misleading, the snippets should have continued to use the same pseudo-code as the
snippet on page 291,
... extends SomeSpecialHttpServlet {

[296] Implicti Object table;


based on JSP 2.0 specification implicit variable exception is of type
java.lang.Throwable and not javax.servlet.jsp.JspException

JSP specification page 78 table JSP.1-7 Implicit Objects Available in Error Pages

(297) Heading;
This should be labelled a "Be the Container" exercise.

(In order to be consistent with text on page 300 where


the answer to p. 297 appears.

{307} 2nd Paragraph;


Yes, you CAN get servlet init parameters from a servlet....
should read:
Yes, you CAN get servlet init parameters from a JSP...

[308] The DD at the top part of the page;


This DD does not work to allow the JSP to obtain the servlet init params.
The proper DD for this is:

<servlet>
<servlet-name>MyTestInit</servlet-name>
<jsp-file>/TestInit.jsp</jsp-file>
<init-param>
<param-name>email</param-name>
<param-value>wecare@wickedlysmart.com</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>MyTestInit</servlet-name>
<url-pattern>/TestInit.jsp</url-pattern>
</servlet-mapping>

{322} Exercise no. 2.;


"...OR place a checkmark in the ignored column if scripting will be treated like other
template text."
should be:
"...OR place a checkmark in the error column if scripting will cause a translation error."

And change the "ignored" column title to "error".

(323 *and* 326) code magnets;


The code magnet should read
<jsp:include page="foo.html"/>
*not*
<jsp:include file="foo.html"/>

(325) Exercise 2;
change the "ignored" column title to "error".

(327) 3rd handwritten note;


AS IS:
Expressions turn into write() statements in the service method.
SHOULD BE:
Expressions turn into out.print() statements in the service method.

{343} 3rd handwritten note;


AS IS:
(Remember: scripting expressions are ALWAYS the argument to the out.write() method.)
SHOULD BE:
(Remember: scripting expressions are ALWAYS the argument to the out.print() method.)

[353] Has this result title;


Has this result
java.lang.InstantiationError: foo.Person

should be

Has this result


java.lang.InstantiationException: foo.Person

{368} Paragraph under Using the dot(.) operator to access...title;


The first variable is either ..., and the thing to the right of the dot is either a
map value(if the first variable is a map) ...

should be

The first variable is either..., and the thing to the right of the dot is either a
map key(if the first variable is a map) ...

(372) Under title In a Servlet;


says: favoriteFood.add("chai ice chream");
possible change: favoriteFood.add("chai ice cream");

(386) above the line divider;


${cookie.userName.valu} should be
${cookie.userName.value}

(391) 2nd paragraph (first A: block);


(a JSP supposed to be ...
should read
(a JSP is supposed to be ...
(393) 3rd item of "What prints for each of these?";
${requestScope[integer] ne 4 and 6 le num || false}
should read:
${requestScope["integer"] ne 4 and 6 le num || false}

(399) First hand-written comment on top left;


Says "This is the same as it was on the previous page..."
should say:
"This is the HTML content that we want on every page in our webapp."

{400} 1st paragraph;


The <jsp:include> standard action appears to do the same thing as the include standard
action.
should be:
The <jsp:include> standard action appears to do the same thing as the include directive.

[404] The bottom diagram;


in the diagram, the translated file name is Contact_jsp.java and the compiled file name is
Contact_jsp.class
it should be Header_jsp.java and Header_jsp.class

(405) In the top left BANG! box;


In the sentence "To help you remember, the include directive <% include
file="foo.jsp"> is used only at translation time (as with all directives)."

It should read "To help you remember, the include directive <%@ include
file="foo.jsp"%> is used only at translation time (as with all directives)."

{405} last sentence in bottom-right comment;


Sentence should end "but that's more obvious with the
include directive.", not "page directive."

{407} whole page;


As the .jspf convention is not supported by default in Tomcat, the following mapping
needs to be added to the application's web.xml for the example to work correctly:
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jspf</url-pattern>
</servlet-mapping>

[407] section 1 and section 2;


Section 2 Contact.jsp;
<%@ include file="Header.jsp" %>
should be
<%@ include file="Header.jspf" %>

(407) Section 3 The Footer file;


The heading for section 3:
3 The Footer file ("Footer.jsp")
should be:
3 The Footer file ("Footer.html")

[416] Be the Container Answers;


The third example will not work for the same reason that the first example doesn't
work, because the attribute is at Request Scope, and the default scope is Page scope.
The handwritten comment for bullet #3 should be the same as for bullet #1.

{420, 428} Question 6, option F;


"${list[list['listIdx']]}"
should read:
"${list[list[listIdx]]}"

[432] Question 17, Option C;


option C is invalid and should not be checked.

{434} Installing JSTL 1.1;


The instructions indicate just jstl.jar file is required to run JSTL in Tomcat. You
also need standard.jar from the webapps/jsp-examples/WEB-INF/lib/ directory.

{446} Bottom "Bang!" box.;


... "target" attribute in the tag seems like it should work like "id" in the <jsp:setProperty>.
should be:
... "target" attribute in the tag seems like it should work like "id" in the <jsp:useBean>.
{447} Answer to second q&a;

Answer talks about using 'scope' attribute for c:set for


'var' or 'target'. Scope attribute is only meaningful for
'var'. Answer needs to be rewritten to remove any reference
to the 'target' attribute.

{448} 2nd handwritten comment;


The scope is optional, and like always - page is the default scope.
should be:
The scope is optional, and when not specified the attribute is removed from all scopes.

{452} first section;


The JSP with the <jsp:include>
last line </body></html
should be </body></html>

(453) Bullet item 1;


The title of the bullet should be "The JSP with the <c:import>"

(465) The box of 'The "Core" library, last item;


<c:forEachToken>
should be:
<c:forTokens>.

[467] 1st paragraph;


..., the DD below describes ...
should be
..., the TLD below describes ...

{471} example 2 "Scripting expressions";


the closing single-quote is in the wrong place

<mine:advice user='<%= request.getAttribute("username")' %> />


should be:
<mine:advice user='<%= request.getAttribute("username") %>' />
(480) Change to "${foo}" rather than "{userName}"

[484] Code snippet, line 12;


Change BeerStyles[] to BeerStyle[]

{499} 1st paragraph, first sentence;


the sentence "the Container searches for tag files in four
locations" needs a period at the end.

{507} BE the Container;


The 2nd sentence in the "BE the Container" paragraph should read
"Assume that the tag handler prints the body of tag."

{513} Sharpen your pencil, First sentence;


Says "What is the result if the thingsDontWork test is false?"
should be:
"What is the result if the thingsDontWork test is True?"

{520, 527, 532} TagSupport Class in the class diagram;


return type of doAfterBody() should be "int" instead of "void"

(527) Sharpen your pencil text;


Try to mplement...
should read:
Try to implement...

(537) First paragraph;


There are two instances of <my:Menu> and one <my:MenuItem>. The code example
below
the text uses tag <mine:Menu> and <mine:MenuItem>.
The instances of "<my:" should be changed to "<mine:".
(537) 3rd paragraph;
Nested tags are used in several places in the JSTL; the <c:choose) tag..
should read:
Nested tags are used in several places in the JSTL; the <c:choose> tag..

(544) Second to last paragraph;


"The Container walks the tag nesting hieararchy until..."
should read:
"The Container walks the tag nesting hierarchy until..."

{548} answer #2;


<%@ tag body-content="tagdependent" %>
should be
<%@ tag body-content="empty" %>

(549) question 1;
first "to" is a typo

[550] question 3;
Option C is invalid.
Unfortunately, that leaves us with a mock question that doesn't have a valid answer.

{555} Question 13, Option E;


The code on Option E should be:
String p = (String) pageContext.getRequest().getAttribute("param");

[557] question 17;


Both tags are declared to be non-empty in the TLD.
should read:
Both tags are declared to be non-empty and non-tag dependent in the TLD.

(558) Question 21, 1st line;


"Given a web app sturcutre:"
should read:
"Given a web app structure:"

(560) Question 4, Handwritten Comments for Option A;


"-Option A is invalid because the doTag method dies return a value".
should read:
"...doTag method does not return a value".

(563) Answer on question 9, written comment on option D;


The written remark at option D belongs to option D of the answer
on question 8 and not question 9.
The comment for question 9 should be:
"-Option D is invalid because it is not a valid return code."

{565} Question 13;


Option E cannot be correct because it assigns the return value of
ServletRequest.getAttribute (an Object) to a String without a cast.
The code on Option E should be:
String p = (String) pageContext.getRequest().getAttribute("param");

{566} Question 15, Items E & F, Handwritten Comments;


The notes for options E and F should be swapped.

[567] question 17;


Both tags are declared to be non-empty in the TLD.
should read:
Both tags are declared to be non-empty and non-tag dependent in the TLD.

[596] 2rd & 3rd paragraph;


Whenever the book says "value greater than zero" should read "non-negative value".
This occurs in paragraph 2 and 3.
Also, the last sentence in paragraph 3 should read:
"If you have two or more servlets with the same value, the Container may
choose the order in which this subset is initialized."

{608} question 8, answer C;


Option C should read:
"The method that retrieves these parameters has a signature that returns an Object."
(where "Object" should be in courier font to indicate the class name, not the generic
concept)
[631] The tomcat-users.xml file;
<user name="Bill" password="coder" roles="Member, Guest" />
should be
<user username="Bill" password="coder" roles="Member, Guest" />

[632] The last XML on the page;

the DD-XML:

<security-role>
<role-name>Admin</role-name>
<role-name>Member</role-name>
<role-name>Guest</role-name>
</security-role>

should read:

<security-role>
<role-name>Admin</role-name>
</security-role>
<security-role>
<role-name>Member</role-name>
</security-role>
<security-role>
<role-name>Guest</role-name>
</security-role>

According to the servlet 2.4 spec, page 145 (13.4.19),


<role-name> is allowed only once within a <security-role>
element.

(633) first call-out in handwriting font:


"mandatory named used by" should be "mandatory name used by"

{635} Lower box, 2nd paragraph;


"If you do NOT specify any <http-element>, then..."
should read:
"If you do NOT specify any <http-method>, then..."
[637] Case 2;
The second row should not have Diane and Annie crossed out.
All of these users would have permission to use the webapp.

(638) arrow on the right of DD;


the 2 arrows should be pointing at /Beer/UpdateRecipes/*, instead of
/Beer/DisplayRecipes/* nor /Beer/UpdateUsers/*

[639] authorization table (first row / last column); Case 1:


Diane has two roles: 'Member' and 'Guest'
So as 'Guest', she has the permission to use the ressource and should not be crossed out.

(642) 1st paragraph;


In HttpSerlvetRequest,
should read:
In HttpServletRequest,

{643}
The deployment descriptor on the right hand side of the page has two errors.
First the closing and opening <web-app> tags should be dropped; this is all a single DD.
Second, there should be only one <role-name> subelement in the <security-role>
element.
Remove the Member and Guest roles as they are not needed in this example.

{648} Sharpen your pencil;


The third missing piece, at the end of the 4th line of the DD section, has a "/" after the
blank box.
This "/" should be before the blank box.

(655) Row 3, step 3;


In the POST diagram the "S" at the end of "HTTPS" is crossed out. It should be
underlined.

[662] question 2, code;


The web.xml configuration code is Question 2 is incorrect.
It should read as follows:
<auth-constraint>
<role-name>Bob</role-name>
</auth-constraint>
<auth-constraint/>
<auth-constraint>
<role-name>Alice</role-name>
</auth-constraint>

(669) 3rd line from bottom;


"Want to manipulate the output from ever servlet in your app"
should read:
"Want to manipulate the output from every servlet in your app"

(670) 3rd paragraph (3rd objective);


Should be 11.2 and not 11.1

{677} Step 2 of the stack;


The last line of the second step reads:
"... until it reaches its chain. doFilter ()call."
Should be:
"... until it reaches its chain. doFilter() call."

(679) LL;
<filter-mapping> element declared at the top of the code ends with </filter>
it should end with
</filter-mapping>

In addition, there is a typesetting problem. The ligature fi is used in the courier


font in all the places where lowercase "fi" occurs (e.g. filter) The fi ligature
should not be used with a monospaced font for typesetting computer code.

(689) Bottom right - number 2;


'When the servlet asks for an it doesn't KNOW that it will get a "special" output stream.'
should read:
'When the servlet asks for an output stream, it doesn't KNOW that it will get a "special"
output stream.'

[691] In the else clause of the code example;


The solution should include the code "fc.doFilter(req, resp);" in the else clause.
{693} 3rd line;
streamUsed != pw
should be:
if ( (streamUsed != null) && (streamUsed == pw) ) {

{693} 15th line;


streamUsed != servletGzipOS
should be:
if ( (streamUsed != null) && (streamUsed == servletGzipOS) ) {

{697, 701} Question 3, first line;


"Given this method in an otherwise properly defined Filter implementation:"
should be:
"Given the class UserRequest is an implementation of HttpServletRequest, and given this
method
in an otherwise properly defined Filter implementation:"

(697) bottom;
The answer to question 3 on p. 701 is given as "E. None of the above".
However, for question 3 on p. 697, there is no choice E.

(699, 703) Question 6, option C;


"C. They can be used even when the application does not supprt HTTP"
should read:
"C. They can be used even when the application does not support HTTP"

(703) question 5;
option D should be checked.

(705) bottom of the page;


"accordion" is misspelled "accordian"

(732) 2nd paragraph;


The comment
//do a data converstaion on the date parameter
should be changed to
//do a data conversion on the date parameter
[741] execute method of BeerSelectAction
ArrayList result = be.getBrands(myForm.getColor());
SHOULD BE
List result = be.getBrands(myForm.getColor());

(777,815) Question 31;


Says:
how would you rite the JSP
Should Be:
how would you write the JSP

[785] Question 43;


options B-E should include the inner <role-name> tags as the read demonstrates here.
Example:
<auth-constraint>
<role-name>Member</role-name>
</auth-constraint>

{785,823} Question 44;


The bullet "* should reduce duplicate code" should be deleted.
It is not a feature of the design pattern described.

(785 and 823): There is a typo in the open tag in Option B. It should read <auth-
constraint>.

[810] Question 22;


we can make the question more clear by making this change:

"Which JSP code would..."


TO
"Given that /segments/footer.html is a static page, which JSP code would..."

{825}: Drop the comment for Option A