The Request-Response Cycle

 < Free Open Study > 



Servlets are designed to receive client requests and to develop a response to return to the client. The client's request is mapped to a servlet by the container. We can specify which client requests are mapped to which servlets by configuring the web application correctly; we will come back to this issue in Chapter 4. The container also has the responsibility of processing the request into an object-oriented format that the servlet can process, which it does by wrapping the request in a ServletRequest object.

Request-Response Interfaces and Wrapper Classes

The ServletRequest interface defines the Request object that will wrap the client request, which is then passed to the servlet for processing. Similarly, the ServletResponse interface defines an object that is passed to the servlet in order to give the servlet access to the container's response sending mechanism.

These interfaces define the methods that are made available to the servlet for interpreting the request and returning a response. The API also makes available two convenience wrapper classes that fully wrap the functionality of their corresponding interfaces.

There are also two convenience wrapper classes included in the Servlet API to wrap the Request and Response objects (javax.servlet.ServletRequestWrapper and javax.servlet.ServletResponseWrapper). They make it easier to implement the Request and Response interfaces and extend their functionality. By default their methods call the methods of the wrapped object.

In this section we are going to take a close look at the servlet Request-Response interfaces. We will also build an example servlet, RequestResponseServlet, which demonstrates the use of the Request and Response objects, and returns the data to the client in HTML format.

Implementing the RequestResponseServlet

The RequestResponseServlet class extends the GenericServlet class. The purpose of the servlet is to generate a page containing two tables, one containing information about the request, the other containing information about the response from the servlet. Here's what the request table looks like:

click to expand

Scrolling down the page brings us to the response table:

click to expand

As you can see, each table simply consists of parameter-value pairs. We'll deal with the meaning of each parameter as we discuss them during the course of the chapter.

The RequestResponseServlet makes use of a simple HTMLTable utility class. This class is designed to simplify the process of creating a HTML table of data, so that we can concentrate on understanding the methods we are calling in the request and response objects. We will take a look at this utility class first, and then we'll discuss the servlet itself.

To run the example, you will need to add the two Java source code files into the basicServlets package source directory. Compile the source code and move the classes into the classes\basicServlets directory, and then restart Tomcat. You can then access the servlet on the following URL:

http://localhost:8080/servletAPI/servlet/basicServlet.RequestResponseServlet

The HTMLTable Utility Class

The HTMLTable utility class is used to provide a simple two column HTML table that may be dynamically created and grown by adding rows to the table. Once complete, the HTMLTable object will output a String or StringBuffer object representing the HTML table. The point of this class is to abstract some of the HTML process into this class, so that we can reuse the code, and so that we can move some of the HTML away from the servlet code. We will reuse this class in the following chapter as well.

We begin the class by creating three StringBuffer class variables to hold the table head code, the foot code and a rows variable to store all of the added rows:

    package basicServlets;    public class HTMLTable {      private StringBuffer head;      private StringBuffer rows;      private StringBuffer foot; 

In the HTMLTable() constructor method we initialize and create the table head and foot objects, and initialize the rows object to be ready to store row data:

      public HTMLTable() {        head = new StringBuffer();        head.append("<table width=\"90%\" align=\"center\">");        head.append("<tr><th width=\"50%\"                             bgcolor=\"lightgrey\">Attribute</td>");        head.append("<th width=\"50%\"                         bgcolor=\"lightgrey\">Value</td></tr>");        rows = new StringBuffer();        foot = new StringBuffer();        foot.append("</table>");      } 

The appendTitleRow() method allows us to add a title to a section of the table:

      public void appendTitleRow(String attribute) {        rows.append("<tr><td colspan=2><b><u>").append(attribute);        rows.append("</u></b></td></tr>");      } 

We provide an appendRow() method to add rows to the table, or strictly speaking to add data to the rows StringBuffer object. We have three versions of this method overloaded, so that we can have not only two String parameters, but we also allow the second variable to be an int or boolean. The last two overloaded methods simply convert the parameter into a String and forward to the first method. This allows easy maintenance or update of the HTML code, if required:

      public void appendRow(String attribute, String value) {        rows.append("<tr><td>").append(attribute);        rows.append("</td><td><code>").append(value);        rows.append("</code></td></tr>");      }      public void appendRow(String attribute, int value) {        appendRow(attribute, new Integer(value).toString());      }      public void appendRow(String attribute, boolean value) {        appendRow(attribute, new Boolean(value).toString());      } 

Finally we provide a toString() method that overrides the Object.toString() method, so that printing a HTMLTable object will automatically call the overridden toString() method and output a well-formatted HTML table. We do this by appending the rows and foot to the head StringBuffer object. Similar to the toString() method, we also provide a toStringBuffer() method that returns the same appended HTML table in StringBuffer format:

      public String toString() {        return head.append(rows).append(foot).toString();      }      public StringBuffer toStringBuffer() {        return head.append(rows).append(foot);      }    } 

The RequestResponseServlet

Our servlet extends the GenericServlet class and implements the service() method to build two tables of information about the Request and Response objects:

    package basicServlets;    import javax.servlet.*;    import javax.servlet.http.*;    import java.io.*;    import java.util.*;    public class RequestResponseServlet extends GenericServlet { 

The service() method calls the getRequestTable() and getResponseTable() methods to build HTML tables of request and response information. These are the real content of the page and we will implement these methods later in this section, as we come to understand the ServletRequest and ServletResponse interfaces in more depth:

      public void service(ServletRequest request, ServletResponse response)                                         throws ServletException, IOException {        StringBuffer requestTable = getRequestTable(request);        StringBuffer responseTable = getResponseTable(request, response); 

Then we display a simple HTML page with the two tables included. This completes the request processing:

        response.setContentType("text/html");        PrintWriter out = response.getWriter();        //HTML page        out.println("<html><head><title>RequestResponseServlet</title>");        out.println("</head><body>");        out.println("<h1>Request Information</h1>" + requestTable + "<hr>");        out.println("<h1>Response Information</h1>" + responseTable);        out.println("</body></html>");        out.close();      } 

So, the most interesting part of the processing of the Request and Response objects takes place in the getRequestTable() and getResponseTable() methods. These methods take their corresponding ServletRequest or ServletResponse objects as parameter. They then use these objects to extract information about the request/response, and to construct a HTML table. As we discuss the methods of the ServletRequest and ServletResponse interfaces, we will develop these methods too.

The ServletRequest Interface

The ServletRequest interface wraps the client request, and provides methods that make the request information available to the servlet.

Obtaining Request Parameter Names and Values

Often the first information that we want to extract from a client request is information about the parameters given as part of the request. This usually tells the servlet what the client is requesting.

To add flexibility to the request, we don't need to know the names of the parameters that will be submitted at development stage. Instead, we call methods that return the names of the parameters contained in the request, and methods that return the values of these parameters.

For example, we can call the getParameterNames() method to receive an Enumeration of String objects corresponding to the names of all the parameters supplied with the request. The method returns an empty Enumeration object if no parameters were supplied:

    public java.util.Enumeration getParameterNames() 

To find the value of a specific parameter we call the getParameter() method:

    public String getParameter(String name) 

This method returns null if the parameter was not included in the request. If more than one value may be returned for the parameter we should use the getParameterValues() method instead:

    public String[] getParameterValues(String name) 

This method returns a String array of values for the specified parameter; we can then iterate through the array to process all the values. The String array is empty if no parameters matching the name are included in the request.

We may also get a Map object, which has a mapping of all of the request parameters' names to their values, using the getParameterMap() method:

    public java.util.Map getParameterMap() 

The names of the parameters are the keys of the Map object, and the values of the Map object are String arrays.

Retrieving Request Parameter Values in getRequestTable()

We start our getRequestTable() method by creating the HTMLTable object that we will use to create the HTML table:

      private StringBuffer getRequestTable(ServletRequest request) {        HTMLTable table = new HTMLTable();        table.appendTitleRow("Parameters"); 

After adding the title row, we use getParameterNames() to get an Enumeration of the parameter names so that we can process the parameters. We use a loop to iterate through the Enumeration:

       Enumeration e = request.getParameterNames();       while (e.hasMoreElements()) {         String paramName = (String)e.nextElement(); 

Once we have extracted the current parameter name, we call the getParameterValues() method on the request object with the name of the parameter we are looking for. This method returns a String array of value(s). Then we loop through the array to add each value associated with the parameter to the table:

         String[] paramValues = request.getParameterValues(paramName);         if (paramValues != null) {           for (int i = 0; i < paramValues.length; i++) {             table.appendRow("Parameter: <code>" + paramName +                             "</code>", paramValues[i]);           }         }       } 

Accessing Request Header Information

There are three methods that allow the servlet to access information provided in the header of the request. To get the size of the request (useful if a file or other large object is attached) we can use the getContentLength() method, which returns the length in bytes, or -1 if it is unknown:

    public int getContentLength() 

The getContentType() method is useful if we wish to determine the data type of the data in the request body:

    public String getContentType() 

It returns the MIME type of the request (if known) or null (if unknown). For example, if the client was submitting serialized Java objects to the servlet, the MIME type would probably be application/x-java-serialized-object which is the standard MIME type for serialized Java objects.

The last method, getProtocol(), will return the protocol's name and version that were used in making the request (for example HTTP/1.1):

    public String getProtocol() 

Accessing Header Information in getRequestTable()

In our example servlet, we append the title to the table and extract the content-length header from the request. If the client supplied this value, it will be some positive integer value. Otherwise, if the client did not supply it, it will be -1. In the case that it is not supplied we indicate this fact, otherwise we print out the request content size:

        table.appendTitleRow("Headers");        int requestLength = request.getContentLength();        if (requestLength == -1) {          table.appendRow("Request Length", "(Not Specified)");        } else {           table.appendRow("Request Length", requestLength);        } 

Then we find the content type and protocol used in the request:

        table.appendRow("Content Type", request.getContentType());        table.appendRow("Request Protocol", request.getProtocol()); 

Using Attributes in the Request

Attributes are the objects (if any) associated with the request. Attributes are similar to request parameters, but instead of being set by the client, they are set by the servlet container, or they may be set by a previous servlet that used the javax.servlet.RequestDispatcher to forward the request and attached information (Java objects) as attributes to the request. Also, instead of just Strings for values, attribute values can be any Java objects.

The getAttributeNames() method is used to return an Enumeration object of the names of the attributes for this request:

    public java.util.Enumeration getAttributeNames() 

The following method returns the specified attribute or null if the attribute does not exist:

    public Object getAttribute(String name) 

The attribute returned is of type Object, so to use it as any other type of object it will have to be cast into its specific class type:

The storeAttribute() method is used to store the specified Object with the name in the request object. It is normally used when the request will be forwarded to another servlet (or filter) for processing:

    public void setAttribute(String name, Object o) 

Conversely, the removeAttribute() method allows us to remove the specified attribute from the request. This is normally used when the request will be forwarded to another servlet (or filter) for processing:

    public void removeAttribute(String name) 

Setting and Accessing Request Attributes in getRequestTable()

Since there are no attributes already set, we will first set two attributes, so that we can access them. Of course, we would not normally need to set them in the same method that we would use them in, but we will demonstrate both here:

       table.appendTitleRow("Attributes");       request.setAttribute("My Attribute", "My Attribute Value");       request.setAttribute("Another Attribute", "123"); 

The code to output the attributes is similar to that used for the request parameters. We retrieve an Enumeration of attribute names, and loop through it, printing out the attribute name and the object stored:

       Enumeration enum = request.getAttributeNames();       while (enum.hasMoreElements()) {         String attributeName = (String)enum.nextElement();         Object attributeValue = request.getAttribute(attributeName);         if (attributeValue != null) {           table.appendRow("Attribute: <code>" + attributeName + "</code>",                           attributeValue.toString());         }       } 

Obtaining Request Path Information

We use path information from the request to interpret the request and gather additional information useful to processing the request. The ServletRequest interface provides a number of useful methods.

This method returns the protocol scheme used in making the request (for example http, https, or ftp);

    public String getScheme() 

For a servlet that may be configured to receive requests on more than one protocol, the scheme is important for the servlet to be able to extract additional information about the request. Different schemes may have different rules for constructing a URL, so the servlet needs to know the scheme so that the URL can be properly interpreted. Not all of the information needs to be included in the URL (for example, if not included, the port is assumed to be the default for that scheme).

An example could be a servlet that is configured to process e-mail (POP) requests and web (HTTP) requests, where in the first case it serves as a mail server, and in the second it could provide web access to the e-mail.

For further information on addressing schemes see: http://www.w3.org/Addressing/schemes.html

The getServerName() method is used to find out the host server name that received this request:

    public String getServerName() 

This is the name by which the client addressed the server. It is possible that a web application may have more than one server name that it can be addressed by. This method will return the IP address if the server is addressed by its IP address instead of a name:

The following method returns the port number on which the server received the request:

    public int getServerPort() 

Various protocols have default ports that requests are made on; for instance HTTP has port 80 by default. However, servers can listen on any free valid port for requests.

Retrieving Request Path Information in getRequestTable()

We can use the methods above to access the request path information in our getRequestTable() method as follows:

       table.appendTitleRow("Path Information");       table.appendRow("Request Scheme", request.getScheme());       table.appendRow("Request Server", request.getServerName());       table.appendRow("Request Port", request.getServerPort()); 

Checking for Secure Connections

The following method is made available to allow the servlet to determine if the request being served was made over a secure connection (for example over HTTPS):

    public boolean isSecure() 

For example, a servlet may check this before allowing the user to enter confidential information such as credit card or other personal/confidential data.

This method is particularly appropriate to filter or gateway servlets, that may be set up to intercept and redirect requests made to resources requiring a secure connection. Web applications transferring personal, payments or other (moderately) sensitive data may require this.

You can find more information on security in Chapter 9.

Checking Security in getRequestTable()

In this example, we will only output whether the request was made over a secure connection, but we could, based on the result, modify the code to redirect to a secure connection, if we wanted:

       table.appendTitleRow("Security");       table.appendRow("Secure Request", request.isSecure()); 

Using Internationalization in the Request

A few useful methods are available to developers of web applications that have international content or audience. These request methods are useful if you need servlets and filters to process and adapt request processing to different international locales and character sets.

A client may send, as part of its request, information on the preferred locales that it wishes to receive a response in. Providing a selection of locales is useful because the servlet may not support the client's first choice, but may support the second or third choice. The order of the locales supplied is the client's order of preference.

The getLocale() method will return the client's first choice of locale to be used in the request. The getLocales() method returns an Enumeration of Locale objects. By default, if no locale is specified by the client, these methods return the default locale for the server (for the getLocales() method this is a Enumeration of a single Locale object):

    public java.util.Locale getLocale()    public java.util.Enumeration getLocales() 

The getCharacterEncoding() method will return the name of the character encoding (null if not specified) used in the request. We may need this method to ensure that the request data is interpreted correctly, using the correct character encoding:

    public String getCharacterEncoding() 

The setCharacterEncoding() method can be used to override the character encoding used in the body of the request. It must be called before reading the request parameters or reading input using getReader() or getInputStream() methods. The default character encoding is ISO-8859-1 (Latin-1):

    public void setCharacterEncoding(String env) 

For more information on character sets see: http://www.iana.org/assignments/character-sets

Using Internationalization in getRequestTable()

To find the locale used in the request (or the server's default if none were specified) we call the getLocale() method on the Request object:

       table.appendTitleRow("Internationalization");       Locale locale = request.getLocale(); 

From the Locale object, we can extract information that we could use to customize our response to the client (see the Java documentation for more information about using the Locale class: http://java.sun.com/j2se/1.4/docs/api/java/util/Locale.html):

       table.appendRow("Preferred Locale", locale.toString());       table.appendRow("Country (ISO Code)", locale.getCountry());       table.appendRow("Country", locale.getDisplayCountry());       table.appendRow("Language", locale.getDisplayLanguage());       table.appendRow("Locale Name", locale.getDisplayName());       table.appendRow("Character Encoding", request.getCharacterEncoding()); 

Reading from the Request

The Servlet API provides two I/O stream wrapper classes for the request input stream and the response output stream. The Request object allows us to read information from the request, such as included files or serialized Java objects. We can interpret the stream as binary or character data according to the method we call.

We use the getInputStream() method to get a ServletInputStream object if we need to read in a file, or serialized Java objects, or similar information from the client's request. We can use the returned object as an InputStream object, if required, which we can wrap in any valid input class (for example ObjectInputStream) to read in the data:

    public ServletInputStream getInputStream() 

Alternatively we can call the getReader() method to get a java.io.BufferedReader object to read the body of the request. We can read in character data using this method and wrap the returned object in a suitable input class to read the data (for example a FileReader could be used to read in a file of character data):

    public java.io.BufferedReader getReader() 

It is important to note that we can only call one of these methods, not both of them. If we try to call one of these methods, after already having called the other one, the method will throw an IllegalStateException to indicate that the other method was called to read the data. We can call the same method a second time, if necessary, to read more data, if the original reference to the input object is not available (such as in a method that is passed the Request object, but not the input object), however, we must ensure that the stream is not previously closed or that the end of the supplied data has not been reached.

Obtaining Client Information

The following methods return information contained in the request about the client:

    public String getRemoteAddr()    public String getRemoteHost() 

The getRemoteAddr() method will return the client's IP address. The server directs the response to this address. We can also access this, but while it may be useful for identifying clients in general terms, on its own it has limitations, because the IP address of a request can be that of a proxy server.

The getRemoteHost() method returns the client's fully-qualified name. Across the web we use names instead of IP addresses to access web sites normally. The mappings of IP addresses to names are stored on Domain Name Servers (DNS). For example, www.apress.com would be the remote host that this method would return if the Apress web server made the request. Note that this also assumes that a DNS is available to the container. If it cannot determine the fully qualified name (either no DNS is available, or the IP address was not recognized) it returns the IP address:

Retrieving Client Information in getRequestTable()

To round off the getRequestTable() method, we will add the clients IP address and name to the table. In this example, both methods might output the IP address (using localhost as the web address), although this depends on your network set-up:

       table.appendTitleRow("Client Information");       table.appendRow("Client IP Address", request.getRemoteAddr());       table.appendRow("Client Name", request.getRemoteHost()); 

We have also finished the method, so we return the table created, in a StringBuffer object.

       return table.toStringBuffer();     } 

Since we have now completed the method, let's remind ourselves of the table that it generates:

click to expand

Creating a RequestDispatcher

Calling the getRequestDispatcher() method from the ServletRequest interface returns a RequestDispatcher object that wraps the resource specified in the path parameter:

    public RequestDispatcher getRequestDispatcher(String path) 

This allows the servlet to forward the request, or to include the requested resources output in its own output. This method will return null if the container cannot return a dispatcher for the requested resource. The path parameter may map to another servlet, or a static resource, such as a HTML file.

The ServletResponse Interface

The ServletResponse object is used to send the servlet's response back to the client. It wraps the response (output stream, header information, data, and so on) in a single interface, allowing access to the methods that prepare and add content to the response.

Setting Content Length and MIME Types

The ServletResponse class determines two methods that can be used to set the content length and type of the response.

The setContentLength() method sets a header indicating the length of the response:

    public void setContentLength(int len) 

Setting this value too low will normally stop the server sending the excess data after the length specified, and most clients will stop reading the response after the specified length. Therefore, it is often better to let the server set this header (if it can buffer the full response before sending) or perhaps to leave it unset.

The second method is the setContentType() method. This is used to set the MIME (Multipurpose Internet Mail Extensions, RFC 2045 and 2046) type of the response. MIME types are used in many protocols other than HTTP to indicate the type of output or file following:

    public void setContentType(String type) 

This method should be called before any output is written to the output stream object. For example:

    response.setContentType("text/html"); 

For standard web pages we always use "text/html", indicating text data in HTML format. If we were returning serialized Java objects we would use "application/x-java-serialized-object".

Using Internationalization in the Response

We can customize the response to the specific audience and we can also specify technical information on the locale and character set used in the response. The getLocale() and setLocale() methods allow access to and the resetting of the Locale of the response:

    public java.util.Locale getLocale()    public void setLocale(java.util.Locale loc) 

The setLocale() method must be called before a call to getWriter() as calling this method sets the character set to that appropriate for the current locale. Calling the setLocale() method after calling getWriter() has no effect, as the character set of the PrintWriter object already has been set.

The getCharacterEncoding() method returns the name of the character set used for the MIME body sent in the response. The default is ISO-8859-1 (Latin-1):

    public String getCharacterEncoding() 

Using Internationalization in getResponseTable()

Let's use what we have learned about the ServletResponse interface so far to begin construction of the getResponseTable() from our example RequestResponseServlet. Similar to the getRequestTable() method, getResponseTable() takes the ServletResponse object as a parameter and uses this object to extract information about the response in order to place it in an HTML table:

      private StringBuffer getResponseTable(ServletRequest request,                                            ServletResponse response) {        HTMLTable table = new HTMLTable(); 

As we did from the Request object, we extract the Locale from the response object, and then print out information about the Locale being used for the response:

        table.appendTitleRow("Internationalization");        Locale locale = response.getLocale();        table.appendRow("Response Locale", locale.toString());        table.appendRow("Country (ISO Code)", locale.getCountry());        table.appendRow("Country", locale.getDisplayCountry());        table.appendRow("Language", locale.getDisplayLanguage());        table.appendRow("Locale Name", locale.getDisplayName()); 

We can also set the Locale for the response (before the getWriter() method has been called), and in this case we are resetting it to its current value. We do this here because, with an international audience, we do not want to upset the responses for any reader. If you want to try setting the locale specifically, you can substitute the locale parameter with Locale.ENGLISH, replacing the ENGLISH constant with that relevant to your location. Check the API for the list of constants available, or construct a new Locale object for a location not specified:

        response.setLocale(locale);        table.appendRow("Character Encoding", response.getCharacterEncoding()); 

Returning Data in the Response

To return data in the body of your servlet's response we need to access the output object from the Response object. We do this by calling one of the following methods:

    public ServletOutputStream getOutputStream()    public java.io.PrintWriter getWriter() 

We can call the getOutputStream() method that returns a ServletOutputStream object, which can be used directly or wrapped in a suitable I/O object (for example ObjectOutputStream for serialized Java objects) to output a response. Calling the getWriter() method instead returns a PrintWriter object that can be used to send text back to the client.

Only one of these methods should be called to send the response back to the client. Calling either constructs the corresponding output object, and we can't construct a second object to write to the same stream. So we need to decide what type of data we will be sending (for character data use getWriter()) back to the client. If it will be a mixture of types, such as a serialized object first (to pass information about the following data) followed by other data (for example a file), use the getOutputStream() method, and wrap the OutputStream in appropriate classes for sending the data back.

Output Buffering

Buffering strategies for different servlet containers vary and are implemented in different ways. The container is not required to implement output buffering, and the choice of strategy used is up to the vendor to decide based on their implementation and their optimum performance objectives. A number of methods are available to servlets to improve or adapt the buffering strategy for their output.

The getBufferSize() method returns the size of the underlying buffer used (returns 0 if no buffering is used):

    public int getBufferSize() 

The setBufferSize() method allows the servlet to suggest a buffer size to the container:

    public void setBufferSize(int size) 

The container may chose not to implement the exact size specified by the servlet, but must implement the size to be at least the size specified. The setBufferSize() method must be called before any content is returned to the client or the method will throw a java.lang.IllegalStateException:

The isCommitted() method allows the servlet to find out if the response has begun to be sent to the client yet:

    public boolean isCommitted() 

The reset() method will clear any data in the buffer and the headers and status code if the response is not yet committed. If the response has been committed, it will throw an IllegalStateException:

    public void reset() 

Similarly, the resetBuffer() method will reset the data in the buffer (but not the headers or status code) and will throw the IllegalStateException if the response has been committed:

    public void resetBuffer() 

The flushBuffer() method will immediately flush the contents of the buffer to the client. This method will commit the response, which means that the status code and headers will be written out to the client:

    public void flushBuffer() 

Once a buffer is full, the container will instantly flush its contents to the client, which will commit the response.

Output Buffering in getResponseTable()

We will call a few of the buffering methods of the Response object and add the results to the table in our getResponseTable() method. We access the buffer size and then append it to the table:

        table.appendTitleRow("Buffering");        int buffer = response.getBufferSize();        table.appendRow("Buffer Size", buffer); 

We extract an attribute that may or may not be set. At this point it is not set, but in the RequestDispatcherServlet that we will see later this may be set. This indicates if the response may be committed without the servlet knowing. The other servlet knows and sets that attribute as an indicator. This indicator prevents us resetting the buffer size after it has been committed:

       String written = (String) request.getAttribute("buffer"); 

Next we increment the buffer size by one, each time this is called, but only if it has not been committed:

        if (!response.isCommitted() && !"written".equalsIgnoreCase(written)) {          response.setBufferSize(buffer + 1);        }        table.appendRow("Is Response Committed",                         new Boolean(response.isCommitted()).toString()); 

It is important to understand that each container request is altering the buffer size, so they have a cumulative effect. If we were to decrease the buffer size, the container may decide to keep a larger buffer size. However the container must implement at least the size we suggest (bigger if it chooses), so increasing the buffer size without careful consideration can cause the servlet to throw an exception due to the excessive memory allocated to the buffer.

start sidebar
Warning 

If you increase the buffer size excessively (to the point where an exception is thrown), you will have to reset the buffer size to a sensible value (by recompiling with a new value, or restarting the server) before you can continue with this servlet.

end sidebar

To see the effects of this try changing the argument to the setBufferSize() method to "buffer * 2". Each time you execute the servlet, you are doubling the buffer size. Depending on your memory allocation, fairly soon your servlet will throw an exception. When you do this, you have to reset the buffer size to something sensible by recompiling (and not with buffer + 1 but with something like 1024), or restarting the server.

At the end of the method, we return the table in a StringBuffer object:

        return table.toStringBuffer();      }    } 

Finally, let's remind you what the table produced by the getResponseTable() method looks like:

click to expand



 < Free Open Study > 



Professional Java Servlets 2.3
Professional Java Servlets 2.3
ISBN: 186100561X
EAN: 2147483647
Year: 2006
Pages: 130

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net