《Java Servlet Programming》读书笔记_2010.06.12

来源:互联网 发布:大学生网络科 编辑:程序博客网 时间:2024/05/17 23:08

2010-6-12

Determining What Was Requested

l  No method directly returns the original Uniform Resource Locator (URL) used by the client to make to make a request.

l  public static StringBuffer javax.servlet.http.HttpUtils.getRequestURL(HttpServletRequest req)

n  This method reconstructs the request URL based on information available in the HttpServletRequest object.

n  return a StringBuffer that includes the scheme(such as HTTP), server name, server port, and extra path information.

n  This method is often used for creating redirect messages and reporting errors.

l  public String HttpServletRequest.getRequestURI()

n  return the Universal Resource Identifier (URI) of the request, before any URL decoding.

l  public String HttpServletRequest.getServletPath()

n  return the part of the URI that refers to the servlet being invoked or null

l  a helpful tick in remembering path information

decoded(getRequestURI) == decoded(getContextPath) + getServletPath + getPathInfo

 

How It Was Requested

l  public String ServletRequest.getScheme()

n  return the scheme used to make this request

n  For HTTP servlets, this method indicates whether the request was made over a secure connection using the Secure Sockets Layer(SSL), as indicated by the scheme https, or if it was an insecure request, as indicated by the scheme http.

l  public String ServletRequest.getProtocol()

n  return the protocol and version number used to make the request or null if no protocol could be determined.

n  The protocol and version number are separated by a slash. For HTTP servlets, he protocol is usually HTTP/1.0 or HTTP/1.1.

l  public String HttpServletRequest.getMethod()

n  return the HTT method used to make the request. Examples include GET, POST, and HEAD.

The service() method of the HttpServlet implementation uses this method in its dispatching of requests.

 

Request Header

       Useful HTTP Request Headers

Header

Usage

Accept

Specifies the media (MIME) types the client prefers to accept, separated by commas. Some older browsers send a separate header for each media type. Each media type is divided into a type and subtype given as type/subtype. An asterisk (*) wildcard is allowed for the subtype (type/*) or for both the type and subtype (*/*). For example:

Accept: image/gif, image/jpeg, text/*, */*

A servlet can use this header to help determine what type of content to return. If this header is not passed as part of the request, the servlet can assume the client accepts all media types.

Accept-Language

Specifies the language or languages that the client prefers to receive, using the ISO-639 standard language abbreviations with an optional ISO-3166 country code. For example:

Accept-Language: en, es, de, ja, zh-TW

This indicates the client user reads English, Spanish, German, Japanese, and Chinese appropriate for Taiwan. By convention, languages are listed in order of preference.

User-Agent

Gives information about the client software. The format of the returned string is relatively free-form but often includes the browser name and version as well as information about the machine on which it is running. Netscape 4.7 on an SGI Indy running IRIX 6.2 reports:

User-Agent: Mozilla/4.7 [en] (X11; U; IRIX 6.2 IP22)

Microsoft Internet Explorer 4.0 running on a Windows 95 machine reports:

User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows 95)

A servlet can use this header to keep statistics or to customize its response based on browser type.

Referer

Gives the URL of the document that refers to the requested URL (that is, the document that contains the link the client followed to access this document).[6] For example:

Referer: http://developer.java.sun.com/index.html

A servlet can use this header to keep statistics or, if there's some error in the request, to keep track of the documents with errors.

Authorization

Provides the client's authorization to access the requested URI, including a username and password encoded in Base64.

      

Accessing header values

l  public String HttpServletRequest.getHeader(String name)

n  return the value of the named header as a String or null if the header was not sent as part of the request.

l  public long HttpServletRequest.getHeader(String name)

n  return the value of the named header as a long (representing a Date) that specifies the number of milliseconds since the epoch) or -1

n  throws an IllegalArgumentException when called on a header whose value cannot be converted to a Date.

n  useful for handling header like Last-Modified an If-Modified-Since

l  public int HttpServletRequest.getIntHeader(String name)

n  retur the value of the named header as an int or -1

n  throws a NumberFormatException when called on a header whose value cannot be converted to an int.

l  public Enumeration HttpServletRequest.getHeaderNames()

n  return the names of all the headers as an Enumeration of String objects or empty Enum…

n  The Servlet API gives servlet container implementations the right to not allow headers to be accessed int this way , in which case this method returns null.

l  public Enumeration HttpServletRequest.getHeaders(String name)

n  return all the values for the given header as an Enumeration of String objects or an empty Enumeration if the header was not sent as part of the request. If the servlet container does not allow access to header information, the call returns null.

n  There’s no getDateHeaders() or getIntHeaders() method.

 

Wading the Input Stream

l  Each request handled by a servlet has an input stream associated with it .

l  The input stream has two purposes:

n  To pass an HTTP servlet the content associated with a POST request

n  To pass a non-HTTP servlet the raw data sent by the client

l  To read character data from the input stream, you should use getReader() to retrieve the input stream as a BufferedReader object:
public BufferedReader ServletRequest.getReader() throws IOException

n  The advantage of using a BufferedReader for reading character-based data is that it should translate charsets as apropriate.

n  This method throws an IllegalStateException if getInputStream() has been called before on this same request.

n  It throws an UnsupportedEncodingException if the character encoding of the input is unsupported or unknown.

l  To read binary data from the input stream, use getInputStream() to retrieve the input stream as a ServletInputStream object:
public ServletInputStream ServletRequest.getInputStream() throws IOException

n  A ServletInputStream is a direct subclass of InputStream an can be treated as a normal InputStream, with the added ability to efficiently read input a line at a time into an array of bytes.

n  The method throws an IllegalStateException if getReader() has been called before on this same request.

l  Once you have the ServletInputStream, you can read a line from it using readLine():
public int ServletInputStream.readLine(byte b[], int offset, int length) throws IOException

n  This method reads bytes from the input stream into the byte array b, starting at an offset in the array given by off.

n  It stops reading when it encounters an /n or when it has read number of bytes. The ending /n character is read into the buffer as well.

n  The method returns the number of bytes read or -1 if the end of the stream is reached.

l  public String ServletRequest.getContentType()

n  return the media type of the content being sent via the input stream or null if the type is not known(such as when there is no data)

l  public int ServletRequest.getContentLength()

n  return the length of the content being sent via the input stream or -1 if this isn’t known.

 

Receiving files using the input stream

l  The POST request is formatted differently than standard application/x-www-form-urlencoded form data and indicates this fact by setting its content type to multipart/form-data.

l  A form for choosing a file to upload:
<FORM ACTION="/servlet/UploadTest" ENCTYPE="multipart/form-data" METHOD=POST>
    What is your name?
   
<INPUT TYPE=TEXT NAME=submitter /><BR>
    Which file do you want to upload?
   
<INPUT TYPE=FILE NAME=file /><BR>
    <INPUT TYPE=SUBMIT />
</
FORM>

 

Extra Attributes

l  public Object ServletRequest.getAttribute(String name)

n  return the value of a server-specific attribute for the request or null if the server does not support the named request attribute.

l  public Enumeration ServletRequest.getAttributeNames()

n  A listing of all current attributes, hard-coded by the server or placed there by servlets, can be obtained with getAttributeNames()

 

5. Sending HTML Information

5.1 The Structure of a Response

l  An HTTP servlet can return three kinds of things to the client: a single status code, any number of HTTP headers, and a response body.

l  Specifically, the HTTP protocol specifies that the status code and headers must be sent before the response body. A servlet, therefore, must be careful to always set its status code and headers before sending any response body to the client.

 

5.2 Sending a Normal Response

l  public void ServletResponse.setContentType(String type)

n  In an HTTP servlet, this method sets the Content-Type HTTP header.

l  public PrintWriter ServletResponse.getWriter() throws IOException

n  return a PrintWriter for writing character-based response data

n  The writer encodes the characters according to whatever charset is given in the content type.

n  throws an IllegalStateException if getOutputStream() has already been called for this response

n  throws an UnsupportedEncodingException if the encoding of the output stream is unsupported or unknown.

l  public ServletOutputStream ServletResponse.getOutputStream() throws IOException

n  return a ServletOutputStream for writing binary(byte-at-a-time) response data.

n  No encoding is performed.

n  This method throws an IllegalStateException if getWriter() has already been called for this response.

n  The ServletOutputStream class resembles the standard Java PrintStream class.

n  As a direct subclass of OutputStream, it makes available the write(), flush(), and close() methods of the OutputStream class.

 

5.3 Using Persistent Connections

l  Persistent connections(sometimes called keep-alive connections) can be used to optimize the way servlets return content to the client.

l  Example: If a page contains 10 graphics along with an applet made up of 25 classes, that’s 36 connection needed to transfer the page.

l  The way persistent connections work is that the server just tells the client how big the response body will be by setting the Content-Length header as part of the response. The client then knows that after that much response body, it has control of the socket again.

l  public void ServletResponse.setContentLength(int len)

n  This method sets the length(in bytes) of the content being returned by the server.

n  In an HTTP servlet, the metod sets the HTTP Content-Length header.

n  If you do call setContentLength(), there are two caveats: a servlet must call this method before sending the response body, and the given length must be exact. If it’s off by even one byte, you have the potential for problems.

 

5.4 Response Buffering

l  A response buffer allows a servlet to write some amount of output with a guarantee that the response won’t be immediately committed. If the servlet finds an error, the status code and headers can still be changed so long as the buffer has not been flushed.

l  Response buffering also provides a simple way to avoid the potentially difficult content length precalculation. A servlet can use buffering to automatically calculate the content length.

l  It is important to note: buffering all the output and sending it all in one batch requires extra memory, and it may delay the time at which a client begins receiving data.

l  It is also important to note that not all servers and not all clients support persistent connections.

 

Controlling the Response Buffer
(Five methods in ServletResponse provide control over response buffering.)

l  public void ServletResponse.setBufferSize(int size)

n  tell the server the minimum buffer size(in bytes) that your servlet will accept

l  public int ServletResponse.getBufferSize()

n  return an int indicating how large the current buffer actually is or in the unlikely event no buffering is used.

l  public Boolean ServletResponse.isCommitted()

n  determine whether any part of the response has actually been sent

n  If this method returns true, it’s too late to change the status code and headers, and the Content-Length cannot be automatically calculated.

l  public void ServletResponse.reset() throws IllegalStateException

n  you can call reset() to clear the response buffer and the currently assigned status code and response headers.

n  must be called before the response has been committed,

l  public void ServletResponse.flushBuffer() throws IOException

n  You can also force any content in the buffer to be written to the client by calling flushBuffer(), allowing the client to begin receiving the content immediately

 

5.5 Status Codes

l  If a servlet doesn’t specifically the status code, the server steps in and sets its value to the default 200 OK status code.

l  The most common status code numbers are defined as mnemonic constants (public final static int fields) in the HttpServletResponse class.

HTTP Status Codes

Mnemonic Constant

Code

Default Message

Meaning

SC_OK

200

OK

The client's request was successful, and the server's response contains the requested data. This is the default status code.

SC_NO_CONTENT

204

No Content

The request succeeded but there was no new response body to return. Browsers receiving this code should retain their current document view. This is a useful code for a servlet when it accepts data from a form but wants the browser view to stay at the form, as it avoids the "Document contains no data" error message.

SC_MOVED_PERMANENTLY

301

Moved Permanently

The requested resource has permanently moved to a new location. Future references should use the new URL in requests. The new location is given by the Location header. Most browsers automatically access the new location.

SC_MOVED_TEMPORARILY

302

Moved Temporarily

The requested resource has temporarily moved to another location, but future references should still use the original URL to access the resource. The new location is given by the Location header. Most browsers automatically access the new location.

SC_UNAUTHORIZED

401

Unauthorized

The request lacked proper authorization. Used in conjunction with the WWW-Authenticate and Authorization headers.

SC_NOT_FOUND

404

Not Found

The requested resource was not found or is not available.

SC_INTERNAL_SERVER_ERROR

500

Internal Server Error

An unexpected error occurred inside the server that prevented it from fulfilling the request.

SC_NOT_IMPLEMENTED

501

Not Implemented

The server does not support the functionality needed to fulfill the request.

SC_SERVICE_UNAVAILABLE

503

Service Unavailable

The service (server) is temporarily unavailable but should be restored in the future. If the server knows when it will be available again, a Retry-After header may also be supplied.

      

Setting a Status Code

l  public void HttpServletResponse.setStatus(int sc)

n  This method sets the HTTP status code to the given value.

n  The setStatus() method should be called before the response is omitted, otherwise the call is ignored.

l  If a servlet sets a status code that indicates an error during the handling of the request, it can call sendError( ) instead of setStatus( )

n  public void HttpServletResponse.sendError(int sc) throws IOException, IllegalStateException

n  public void sendError(int sc, String sm) throws IOException, IllegalStateException

n  The sendError() method causes the server to generate and send an appropriate server-specific page describing the error, letting the servlet error page have a similar appearance to other server error pags.

n  This method performs an implicit reset on the response buffer before generating the error page.

 

Improving ViewFile Using Status Codes

// Return the file

try {

  ServletUtils.returnFile(file, out);

}

catch (FileNotFoundException e) {

  out.println("File not found");

}

 

// Return the file
try {
  ServletUtils.returnFile(file, out);
}
catch (FileNotFoundException e) {
 //generally appears identical to the server's normal error page
  res.sendError(res.SC_NOT_FOUND);
}

 

原创粉丝点击