Popular Posts

Monday, April 13, 2009

Generating the Server Response: HTTP Status Codes

Generating the Server Response: HTTP Status Codes :

When a Web server responds to the request from the browser or other Web client, the response typically consists of a status line, some response headers, a blank line, and the document

Specifying Status Codes

As described above, the HTTP response status line consists of the HTTP version, a status code, and an associated message. Since the message is directly associated with the status code and the HTTP version is determined by the server, all the servlet needs to do is to set status code. The way to do that is by the setStatus method of the HttpServletResponse.

The setStatus method takes the int (the status code) as an argument, but instead of using explicit numbers, it is clearer and more reliable to use the constants defined in HttpServletResponse. The name of each constant is derived from standard HTTP 1.1 message for each constant, all uppercase with a prefix of SC(for Status Code) and spaces changed to underscores. Thus, since the message for 404 is Not Found, the equivalent constant in the HttpServletResponse is SC_NOT_FOUND There are two exceptions however. For some odd reason the constant for code 302 is derived from the HTTP 1.0 message, not the HTTP 1.1 message, and the constant for the code 307 is missing altogether.

Setting the status code does not always mean that you don't need to the return a document. For example, although most servers will generate the small "File Not Found" message for 404 responses, a servlets might want to customize this response. However, if you do this, you need to be sure to call response.setStatus before sending any content via PrintWriter.

Although the general method of setting status codes is simply to the call response.setStatus(int), there are two common cases where a shortcut method in the HttpServletResponse is provided. The sendError method generates the 404 response along with a short message formatted inside an HTML document. And the sendRedirect method generates the 302 response along with a Location header indicating the URL of the new document.


HTTP 1.1 Status Codes and Their Meaning

Following is the list of all the available HTTP 1.1 status codes, along with their associated message and interpretation. You should be cautious in using status codes that are available only in HTTP 1.1, since many browsers still only support HTTP 1.0. If you do use the status codes specific to HTTP 1.1, in most cases you want to either explicitly check the HTTP version of request (via the getProtocol method of the HttpServletRequest) or reserve it for situations when no HTTP 1.0 status code would be particularly meaningful to the client anyhow.















100 Continue Continue with partial request. (New in HTTP 1.1)
101 Switching Protocols

Server will comply with Upgrade header and change to different protocol. (New in HTTP 1.1)
200 OK

Everything's fine; document follows for GET and POST requests. This is the default for servlets; if you don't use setStatus, you'll get this.
201 Created

Server created a document; the Location header indicates its URL.
202 Accepted Request is being acted upon, but processing is not completed.
203 Non-Authoritative Information Document is being returned normally, but some of the response headers might be incorrect since a document copy is being used. (New in HTTP 1.1)
204 No Content

No new document; browser should continue to display previous document. This is a useful if the user periodically reloads a page and you can determine that the previous page is already up to date. However, this does not work for pages that are automatically reloaded via the Refresh response header or the equivalent header, since returning this status code stops future reloading. JavaScript-based automatic reloading could still work in such a case, though
205 Reset Content

No new document, but browser should reset document view. Used to force browser to clear CGI form fields. (New in HTTP 1.1)
206 Partial Content

Client sent a partial request with a Range header, and server has fulfilled it. (New in HTTP 1.1)
300 Multiple Choices

Document requested can be found several places; they'll be listed in the returned document. If server has a preferred choice, it should be listed in the Location response header.
301 Moved Permanently

Requested document is elsewhere, and the URL for it is given in the Location response header. Browsers should automatically follow the link to the new URL.
302 Found

Similar to 301, except that the new URL should be interpreted as a temporary replacement, not a permanent one. Note: the message was "Moved Temporarily" in HTTP 1.0, and the constant in HttpServletResponse is SC_MOVED_TEMPORARILY, not SC_FOUND.Very useful header, since browsers automatically follow the link to the new URL. This status code is so useful that there is a special method for it, sendRedirect. Using response.sendRedirect(url) has a couple of advantages over doing response.setStatus(response.SC_MOVED_TEMPORARILY) and response.setHeader("Location", url). First, it is easier. Second, with sendRedirect, the servlet automatically builds a page containing the link (to show to older browsers that don't automatically follow redirects). Finally, sendRedirect can handle relative URLs, automatically translating them to absolute ones.

Note that this status code is sometimes used interchangeably with 301. some servers will send 301 and others will send 302.

Technically, browsers are only supposed to automatically follow the redirection if the original request was GET. See the 307 header for details.





Accessing the Standard CGI Variables

Accessing the Standard CGI Variables:

To build the successful web application, you often need to know a lot about the environment in which it is running.

You may need to find out about server that is executing your servlets or the specifics of the client that is sending requests. And no matter what kind of environment the application is running in, you most certainly need the information about the requests that the application is handling.

Advantages of Using Servlets Over CGI

* Stronger type checking. In other words, more help from compiler in catching errors. A CGI program uses one function to retrieve its environment variable. Many errors cannot be found until they cause runtime problem. Let's look at how both a CGI program and servlets find the port on which its server is running.

A CGI script written in Perl call: $port = $ENV{'SERVER_PORT'}; port is an untyped variable. A CGI program written in C call: The chance for accidental errors is also high. The environment variable name could be misspelled or the data type might not match what the environment variable returns.

A servlet, on the other hand, call:

int port = req.getServerPort()

This eliminates a lot of the accidental errors because the compiler can guarantee there are no misspellings and each return type is as it should be.
*

Delayed calculation. When the server launches a CGI program, the value for each and every environment variable must be precalculated and passed, whether the CGI program uses it or not. A server launching the servlets has the option to improve performance by delaying these calculations and performing them on demand as needed.
*

More interaction with server. Once the CGI program begins execution, it is untethered from its server. The only communication path available to program is its standard output. A servlet, however, can also work with the server. As discussed in the last chapter, a servlet operates either within the server (when possible) or as connected process outside the server (when necessary). Using this connectivity, a servlet can make ad hoc requests for calculated the information that only the server can provide. For example, a servlet can have its server do arbitrary path translation, taking into consideration the server's aliases and virtual paths.



CGI Environment Variables and the Corresponding Servlet Methods











CGI Environment VariableHTTP Servlet Method
SERVER_NAMEreq.getServerName()
SERVER_SOFTWAREgetServletContext().getServerInfo()
SERVER_PROTOCOLreq.getProtocol()
SERVER_PORTreq.getServerPort()
REQUEST_METHODreq.getMethod()
PATH_INFOreq.getPathInfo()
PATH_TRANSLATEDreq.getPathTranslated()
SCRIPT_NAMEreq.getServletPath()
DOCUMENT_ROOTreq.getRealPath("/")

Sunday, April 12, 2009

Handling the Client Request: HTTP Request Headers

*When the HTTP client (e.g. a browser) sends a request, it is required to supply a request line (usually GET or POST).

* If it wants to, it can also send the number of headers, all of which are optional except for Content-Length, which is required only for POST requests

HTTP Request Header Methods Available in Servlets

General:

-getHeader (header name is not case sensitive)
-getHeaderNames
-getHeaders
Specialized

-getCookies
-getAuthType and getRemoteUser
-getContentLength
-getContentType
-getMethod
-getRequestURI
-getQueryString
-getDateHeader
-getIntHeader
-Related info
-getProtocol


An Overview of Request Headers

When the HTTP client (e.g. a browser) sends a request, it is required to supply a request line (usually GET or POST). If it wants to, it can also send the number of headers, all of which are optional except for Content-Length, which is required only for POST requests. Here are the most common headers:

* Accept The MIME types that the browser prefers.
* Accept-Charset The character set that the browser expects.
*

Accept-Encoding The types of data encodings (such as gzip) that the browser knows how to decode. Servlet can explicitly check for gzip support and return gzipped HTML pages to browsers that support them, setting the Content-Encoding response header to indicate that they are gzipped. In many cases, this can reduce page download times by a factor of five or ten.
*

Accept-Language The language the browser is expecting, in case the server has versions in more than the one language.
*

Authorization Authorization info, usually in response to the WWW-Authenticate header from the server.
*

Connection Use persistent connection? If a servlet get a Keep-Alive value here, or gets a request line indicating HTTP 1.1 (where persistent connections are the default), it may be able to take advantage of persistent connections, saving significant time for Web pages that include several small pieces (images or applet classes). To do this, it needs to send the Content-Length header in the response, which is most easily accomplished by writing into a ByteArrayOutputStream, then looking up the size just before writing it out.
*

Content-Length (for POST messages, how much the data is attached)
*

Cookie (one of most important headers; see separate section in this tutorial on handling cookies)
*

From (email address of the requester; only used by Web spiders and other custom clients, not by browsers)
* Host (host and the port as listed in the original URL)
*

If-Modified-Since (only return documents newer than this, otherwise send the 304 "Not Modified" response)
*

Pragma (the no-cache value indicates that the server should return the fresh document, even if it is a proxy with a local copy)
*

Referer (the URL of the page containing the link the user followed to get to the current page)
*

User-Agent (type of the browser, useful if servlet is returning browser-specific content)
*

UA-Pixels, UA-Color, UA-OS, UA-CPU (nonstandard header sent by some Internet Explorer versions, indicating screen size, color depth, operating system, and cpu type used by the browser's system)



Reading Request Headers from Servlets

Reading headers is the very straightforward; just call the getHeader method of the HttpServletRequest, which returns a String if the header was supplied on this request, null otherwise. However, there are the couple of headers that are so commonly used that they have special access methods. The getCookies method returns contents of the Cookie header, parsed and stored in an array of Cookie objects. See the separate section of this tutorial on cookies. The getAuthType and getRemoteUser methods break Authorization header into its component pieces. The getDateHeader and getIntHeader methods read the specified header and then convert them to Date and int values, respectively.

Rather than looking up one of the particular header, you can use the getHeaderNames to get an Enumeration of all header names received on this particular request.

Finally, in addition to looking up request headers, you can get information on the main request line itself. The getMethod method returns the main request method (normally GET or POST, but things like HEAD, PUT, and DELETE are possible). The getRequestURI method returns URI (the part of the URL that came after the host and port, but before the form data). The getRequestProtocol returns third part of the request line, which is generally "HTTP/1.0" or "HTTP/1.1".