Concurrent access can arise in sev-eral situations: con-• Multiple web components accessing objects stored in the web context • Multiple web components accessing objects stored in a sess
Trang 1S ERVLET L IFE C YCLE 141
The listeners.ContextListener class creates and removes the databasehelper and counter objects used in the Duke’s Bookstore application Themethods retrieve the web context object fromServletContextEvent and thenstore (and remove) the objects as servlet context attributes
public void contextInitialized(ServletContextEvent event) { context = event.getServletContext();
try { BookDB bookDB = new BookDB();
BookDB bookDB = context.getAttribute(
Specifying Event Listener Classes
You specify a listener class for a WAR in the deploytool Event Listenersinspector (see Event Listeners (page 126))
Trang 2Handling Errors
Any number of exceptions can occur when a servlet is executed The web tainer will generate a default page containing the messageA Servlet Excep- tion Has Occurred when an exception occurs, but you can also specify that thecontainer should return a specific error page for a given exception You specifyerror pages for a WAR in the deploytool File Ref’s inspector (ErrorMapping (page 126))
con-Sharing Information
Web components, like most objects, usually work with other objects to plish their tasks There are several ways they can do this They can use privatehelper objects (for example, JavaBeans components), they can share objects thatare attributes of a public scope, and they can invoke other web resources TheJava Servlet technology mechanisms that allow a web component to invoke otherweb resources are described in Invoking Other Web Resources (page 156)
web context javax.servlet.
ServletRequest
Web components handling the request.
Trang 3S HARING I NFORMATION 143
Figure 13 shows the scoped attributes maintained by the Duke’s Bookstore
application
Figure 13 Duke’s Bookstore Scoped Attributes
Controlling Concurrent Access to Shared Resources
In a multithreaded server, it is possible for shared resources to be accessed currently Besides scope object attributes, shared resources include in-memorydata such as instance or class variables and external objects such as files, data-base connections, and network connections Concurrent access can arise in sev-eral situations:
con-• Multiple web components accessing objects stored in the web context
• Multiple web components accessing objects stored in a session
hitCounter bookDB orderCounter
Web context attributes Session
attribute cart
Trang 4• Multiple threads within a web component accessing instance variables Aweb container will typically create a thread to handle each request If youwant to ensure that a servlet instance handles only one request at a time, aservlet can implement the SingleThreadModel interface If a servletimplements this interface, you are guaranteed that no two threads will exe-cute concurrently in the servlet’s service method A web container canimplement this guarantee by synchronizing access to a single instance ofthe servlet, or by maintaining a pool of web component instances and dis-patching each new request to a free instance This interface does not pre-vent synchronization problems that result from web components accessingshared resources such as static class variables or external objects.
When resources can be accessed concurrently, they can be used in an tent fashion To prevent this, you must control the access using the synchroniza-tion techniques described in the Threads lesson in the Java Tutorial
inconsis-The Duke’s Bookstore database helper object BookDB maintains a databaseconnection that is referenced by an instance variable namedcon Only one serv-let can use connection at a time Since the servlets accessing this object are mul-tithreaded, access to theconvariable is controlled by the synchronized methods
getConnection andreleaseConnection
private Connection con;
private boolean conFree = true;
public BookDB () throws Exception { try {
InitialContext ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup(dbName);
try { wait();
} catch (InterruptedException e) { .
} } conFree = false;
notify();
return con;
Trang 5I NITIALIZING A S ERVLET 145
} protected synchronized void releaseConnection() { while (conFree == true) {
try { wait();
} catch (InterruptedException e) { .
} } conFree = true;
initmethod of theServletinterface A servlet that cannot complete its ization process should throwUnavailableException
initial-All the servlets that access the bookstore database (BookStoreServlet, logServlet,BookDetailsServlet, andShowCartServlet)initialize a variable
Cata-in theirinitmethod that points to the database helper object created by the webcontext listener:
public class CatalogServlet extends HttpServlet { private BookDB bookDB;
public void init() throws ServletException { bookDB = (BookDB)getServletContext().
getAttribute("bookDB");
if (bookDB == null) throw new UnavailableException("Couldn't get database.");
} }
Writing Service Methods
The service provided by a servlet is implemented in the servicemethod of a
GenericServlet, thedoMethodmethods (whereMethodcan take the valueGet,
Delete,Options,Post,Put,Trace) of anHttpServlet, or any other
Trang 6protocol-specific methods defined by a class that implements theServletinterface In therest of this chapter, the term “service method” will be used for any method in aservlet class that provides a service to a client.
The general pattern for a service method is to extract information from therequest, access external resources, and then populate the response based on thatinformation
For HTTP servlets, the correct procedure for populating the response is to firstfill in the response headers, then retrieve an output stream from the response, andfinally write any body content to the output stream Response headers mustalways be set before a PrintWriter or ServletOutputStream is retrievedbecause the HTTP protocol expects to receive all headers before body content.The next two sections describe how to get information from requests and gener-ate responses
Getting Information From Requests
A request contains data passed between a client and the servlet All requestsimplement the ServletRequest interface This interface defines methods foraccessing the following information:
• Parameters, which are typically used to convey information between ents and servlets
cli-• Object-valued attributes, which are typically used to pass informationbetween the servlet container and a servlet or between collaborating serv-lets
• Information about the protocol used to communicate the request and theclient and server involved in the request
• Information relevant to localizationFor example, in CatalogServlet the identifier of the book that a customerwishes to purchase is included as a parameter to the request The following codefragment illustrates how to use thegetParametermethod to extract the identi-fier:
String bookId = request.getParameter("Add");
if (bookId != null) { BookDetails book = bookDB.getBookDetails(bookId);
You can also retrieve an input stream from the request and manually parse thedata To read character data, use the BufferedReader object returned by the
Trang 7W RITING S ERVICE M ETHODS 147
request’sgetReadermethod To read binary data, use theServletInputStream
returned bygetInputStream.HTTP servlets are passed an HTTP request object,HttpServletRequest, whichcontains the request URL, HTTP headers, query string, and so on
An HTTP request URL contains the following parts:
http://[host]:[port][request path]?[query string]
The request path is further composed of the following elements:
• Context path: A concatenation of’/’with the context root of the servlet’sJ2EE application
• Servlet path: The path section that corresponds to the component alias
that activated this request This path starts with a’/’
• Path info: The part of the request path that is not part of the context path
or the servlet path
Table 14 gives some examples of how the URL will be broken down if the text path is/catalog, and the aliases are as listed in Table 13:
con-Table 13 Aliases
Table 14 Request Path Elements
/catalog/help/feedback.jsp /help/feedback.jsp null
Trang 8Query strings are composed of a set of parameters and values Individual eters are retrieved from a request with thegetParametermethod There are twoways to generate query strings:
param-• A query string can explicitly appear in a web page For example, an HTMLpage generated by the CatalogServlet could contain the link <a href="/bookstore1/catalog?Add=101">Add To Cart</a> Cata- logServlet extracts the parameter namedAdd as follows:
String bookId = request.getParameter("Add");
• A query string is appended to a URL when a form with a GET HTTPmethod is submitted In the Duke’s Bookstore application, Cash- ierServletgenerates a form, a user name input to the form is appended
to the URL that maps toReceiptServlet, andReceiptServlet extractsthe user name using thegetParameter method
Constructing Responses
A response contains data passed between a server and the client All responsesimplement theServletResponseinterface This interface defines methods thatallow you to:
• Retrieve an output stream to use to send data to the client To send ter data, use the PrintWriter returned by the response’s getWriter
charac-method To send binary data in a MIME body response, use the letOutputStreamreturned bygetOutputStream To mix binary and textdata, for example, to create a multipart response, use aServletOutput- Stream and manage the character sections manually
Serv-• Indicate the content type (for example,text/html), being returned by theresponse A registry of content type names is kept by IANA at:
• Set localization information
Trang 9W RITING S ERVICE M ETHODS 149
HTTP response objects, HttpServletResponse, also have fields representingHTTP headers such as
• Status codes, which are used to indicate the reason of a request is not isfied
sat-• Cookies, which are used to store application-specific information at the ent Sometimes cookies are used to maintain an identifier for tracking auser’s session (see Maintaining Client State (page 160))
cli-InDuke’s Bookstore,BookDetailsServletgenerates an HTML page that plays information about a book which the servlet retrieves from a database Theservlet first sets response headers: the context type of the response and the buffersize The servlet buffers the page content because the database access can gener-ate an exception that would cause forwarding to an error page By buffering theresponse, the client will not see a concatenation of part of aDuke’s Bookstore
dis-page with the error dis-page should an error occur ThedoGetmethod then retrieves
aPrintWriter from the response
For filling in the response, the servlet first dispatches the request to let, which generates a common banner for all the servlets in the application
BannerServ-This process is discussed in Including the Content of Another Resource in theResponse (page 157) Then the servlet retrieves the book identifier from arequest parameter and uses the identifier to retrieve information about the bookfrom the bookstore database Finally the servlet generates HTML markup thatdescribes the book information and commits the response to the client by callingtheclose method on thePrintWriter
public class BookDetailsServlet extends HttpServlet { public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { // set headers before accessing the Writer response.setContentType("text/html");
response.setBufferSize(8192);
PrintWriter out = response.getWriter();
// then write the response out.println("<html>" + "<head><title>Book Description</title></head>");
// Get the dispatcher; it gets the banner to the user RequestDispatcher dispatcher =
getServletContext().
getRequestDispatcher("/banner");
if (dispatcher != null)
Trang 10dispatcher.include(request, response);
//Get the identifier of the book to display String bookId = request.getParameter("bookId");
if (bookId != null) { // and the information about the book try {
BookDetails bd = bookDB.getBookDetails(bookId);
.
//Print out the information obtained out.println("<h2>" + bd.getTitle() + "</h2>" + .
} catch (BookNotFoundException ex) { response.resetBuffer();
throw new ServletException(ex);
} } out.println("</body></html>");
out.close();
} } BookDetailsServlet generates a page that looks like:
Trang 11F ILTERING R EQUESTS AND R ESPONSES 151
Filtering Requests and Responses
A filter is an object that can transform the header and/or content of a request orresponse Filters differ from web components in that they usually do not them-selves create a response In particular, a filter should not have any dependencies
on a web resource for which it is acting as a filter so that it can be composablewith more than one type of web resource The main tasks that a filter can per-form are:
• Modify the request headers and data by providing a customized version ofthe request
• Modify the response headers data by providing a customized version of theresponse
• Interact with external resourcesApplications of filters include authentication, logging, image conversion, datacompression, encryption, tokenizing streams, XML transformations, and so on
Trang 12You can configure web components and static resources to be filtered by zero,one, or more filters in a specific order Thus, to use filters you must:
• Define the filter class
• Specify the mapping of filters to web components or static resources
Defining the Filter Class
You define a filter class by implementing theFilterinterface The most tant method in this interface is the doFiltermethod, which is passed request,response, and filter chain objects This method can perform the followingactions:
impor-• Examine the request headers
• Wrap the request object with a customized implementation of questorHttpServletRequestif it wishes to modify request headers ordata
ServletRe-• Wrap the response object with a customized implementation of ResponseorHttpServletResponseif it wishes to modify response head-ers or data
Servlet-• Invoke the next entity in the filter chain If the current filter is the last filter
in the chain that ends with the target web component or static resource, thenext entity is the resource at the end of the chain; otherwise, it is the nextfilter that was configured in the WAR It invokes the next entity by callingthe doFilter method on the chain object (passing in the request andresponse it was called with, or the wrapped versions it may have created).Alternatively, it can choose to block the request by not making the call toinvoke the next entity In the latter case, the filter is responsible for fillingout the response
• Examine response headers after it has invoked the next filter in the chain
• Throw an exception to indicate an error in processingThe Duke’s Bookstore application uses the filters HitCounterFilter and
OrderFilter to increment and log the value of a counter when the entry andreceipt servlets are accessed
In the doFiltermethod, both filters retrieve the servlet context from the filterconfiguration object so that they can access the counters stored as contextattributes When you write the filter, you must implement the [set|get]Filter- Configmethods ThesetFilterConfigmethod is called by the container whenthe filter is instantiated After the filters have completed application-specific pro-
Trang 13F ILTERING R EQUESTS AND R ESPONSES 153
cessing, they invokedoFilteron the filter chain object passed into the original
doFilter method
In addition to logging the value of the hit counter, HitCounterFilter alsoinserts the value of the counter into the response It does this by wrapping the
HttpServletResponseWrapper The wrapped response is passed to the nextobject in the filter chain, which isBookStoreServlet When BookStoreServ- let calls getWriter on the wrapper, it receives a stand-in print writer imple-mented by FilterPrintWriter This layering of print writers is necessarybecause normally a servlet closes a print writer when it completes and then thefilter would not be able to print to that writer BookStoreServlet writes itsresponse into the FilterPrintWriter When chain.doFilter returns, Hit- CounterFilterretrieves the servlet’s response from FilterPrintWriterwiththe getDatamethod, and writes it to the originalPrintWriter The filter theninserts the value of the counter into the originalPrintWriter
public final class OrderFilter implements Filter { private FilterConfig filterConfig = null;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (filterConfig == null) return;
StringWriter sw = new StringWriter();
PrintWriter writer = new PrintWriter(sw);
Counter counter = (Counter)filterConfig.
PrintWriter out = response.getWriter();
CharResponseWrapper wrapper = new CharResponseWrapper(
(HttpServletResponse)response);
chain.doFilter(request, wrapper);
Trang 14out.write(wrapper.getData());
out.println("<center>You are visitor number <font color='red'>" + counter.getCounter() + "</font></center>");
} public FilterConfig getFilterConfig() { return (this.filterConfig);
} public void setFilterConfig(FilterConfig filterConfig) { this.filterConfig = filterConfig;
} } public class CharResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
public char[] getData() { return output.toCharArray();
} public CharResponseWrapper(HttpServletResponse response){ super(response);
output = new CharArrayWriter();
} public PrintWriter getWriter(){
return new FilterPrintWriter(output);
} } class FilterPrintWriter extends PrintWriter { private PrintWriter writer;
public FilterPrintWriter(Writer output) { super(output);
writer = new PrintWriter(output);
} public void println(String s) { writer.println(s);
} }
Trang 15F ILTERING R EQUESTS AND R ESPONSES 155
Figure 14 shows the entry page for Duke’s Bookstore with the hit counter
Figure 14 Duke’s Bookstore
Specifying Filter Mappings
A web container uses filter mappings to decide how to apply filters to webresources A filter mapping matches a filter to a web component by name or toweb components and static resources by URL pattern The filters are invoked inthe order that filter mappings appear in the filter mapping list of a WAR Youspecify a filter mapping list for a WAR in the deploytool Filter Mappinginspector (see Filter Mapping (page 127))
Trang 16Table 15 contains the filter mapping list for theDuke’s Bookstoreapplication.The filters are matched by URL mapping and each filter chain contains only onefilter.
Invoking Other Web Resources
Web components can invoke other web resources in two ways: indirect anddirect
A web component indirectly invokes another web resource when it embeds aURL that points to another web component in content returned to a client In the
Duke’s Bookstoreapplication, most web components contain embedded URLsthat point to other web components For example, ReceiptServlet indirectlyinvokes theCatalogServletthrough the embedded URL /bookstore1/cata- log
A web component can also directly invoke another resource while it is executing.There are two possibilities: it can include the content of another resource, or itcan forward a request to another resource
To invoke a resource available on the server that is running a web component,you must first obtain a RequestDispatcher using the getRequestDis- patcher("URL") method
You can get a RequestDispatcher from either a request or the web context,however, the two methods have slightly different behavior The method takes thepath to the requested resource as an argument A request can take a relative path(that is, one that does not begin with a ’/’), but the web context requires anabsolute path If the resource is not available, or if the server has not imple-mented aRequestDispatcherobject for that type of resource,getRequestDis- patcher will return null Your servlet should be prepared to deal with thiscondition
Table 15 Duke’s Bookstore Filter Mapping List
Trang 17I NVOKING O THER W EB R ESOURCES 157
Including the Content of Another Resource in the Response
It is often useful to include content of another resource, for example, banner tent or copyright information, in the response returned from a web component
con-To include the content of another resource, invoke the include method of a
RequestDispatcher:
include(request, response);
If the resource is static, the includemethod enables programmatic server-sideincludes If the resource is a web component, the effect of the method is to sendthe request to the included web component, execute the web component, andthen include the result of the execution in the response from the containing serv-let An included web component has access to the request object, but it is limited
in what it can do with the response object:
• It can write to the body of and commit a response
• It cannot set headers or call any method (for example, setCookie) thataffects the headers of the response
The banner for theDuke’s Bookstoreapplication is generated by let Note that bothdoGetanddoPostmethods are implemented becauseBan- nerServlet can be dispatched from either method in a calling servlet
BannerServ-public class BannerServlet extends HttpServlet { public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { PrintWriter out = response.getWriter();
out.println("<body bgcolor=\"#ffffff\">" + "<center>" + "<hr> <br> " + "<h1>" + "<font size=\"+3\" color=\"#CC0066\">Duke's </font>" + <img src=\"" + request.getContextPath() +
"/duke.books.gif\">" + "<font size=\"+3\" color=\"black\">Bookstore</font>" + "</h1>" + "</center>" + "<br> <hr> <br> ");
} public void doPost (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { PrintWriter out = response.getWriter();