Sun 的Servlet API 文档

本文介绍了Servlet,它是可插入Java Web服务器的组件,能提供自定义服务。阐述了Servlet在系统架构中的角色,如中间层处理、代理服务器、协议支持等,还提及HTML支持、安全和线程问题。此外,对比了JSDK 1.0和JSDK 2.0,介绍了JSDK 2.0的新特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A servlet is a Java component that can be plugged into a Java-enabled web server to provide custom services. These services can include:

  • New features
  • Runtime changes to content
  • Runtime changes to presentation
  • New standard protocols (such as FTP)
  • New custom protocols

Servlets are designed to work within a request/response processing model. In a request/response model, a client sends a request message to a server and the server responds by sending back a reply message. Requests can come in the form of an

  HTTP
  URL,
  FTP,
  URL,
or a custom protocol.

The request and the corresponding response reflect the state of the client and the server at the time of the request. Normally, the state of the client/server connection cannot be maintained across different request/response pairs. However, session information is maintainable with servlets through means to be described later.

The Java Servlet API includes several Java interfaces and fully defines the link between a hosting server and servlets. The Servlet API is defined as an extension to the standard JDK. JDK extensions are packaged under javax--the root of the Java extension library tree. The Java Servlet API contains the following packages:

Servlets are a powerful addition to the Java environment. They are fast, safe, reliable, and 100% pure Java. Because servlets plug into an existing server, they leverage a lot of existing code and technology. The server handles the network connections, protocol negotiation, class loading, and more; all of this work does not need to be replicated! And, because servlets are located at the middle tier, they are positioned to add a lot of value and flexibility to a system.

In this course you will learn about the Servlet API and you will get a brief tour of the types of features servlets can implement.

Architectural Roles for Servlets

Because of their power and flexibility, servlets can play a significant role in a system architecture. They can perform the application processing assigned to the middle tier, act as a proxy for a client, and even augment the features of the middle tier by adding support for new protocols or other features. A middle tier acts as the application server in so called three-tier client/server systems, positioning itself between a lightweight client like a web browser and a data source.

Middle-Tier Process

 

In many systems a middle tier serves as a link between clients and back-end services. By using a middle tier a lot of processing can be off-loaded from both clients (making them lighter and faster) and servers (allowing them to focus on their mission).

One advantage of middle tier processing is simply connection management. A set of servlets could handle connections with hundreds of clients, if not thousands, while recycling a pool of expensive connections to database servers.

Other middle tier roles include:

  • Business rule enforcement
  • Transaction management
  • Mapping clients to a redundant set of servers
  • Supporting different types of clients such as pure HTML and Java capable clients
Proxy Servers

When used to support applets, servlets can act as their proxies. This can be important because Java security allows applets only to make connections back to the server from which they were loaded.

If an applet needs to connect to a database server located on a different machine, a servlet can make this connection on behalf of the applet.

Protocol Support

The Servlet API provides a tight link between a server and servlets. This allows servlets to add new protocol support to a server. (You will see how HTTP support is provided for you in the API packages.) Essentially, any protocol that follows a request/response computing model can be implemented by a servlet. This could include:

  • SMTP
  • POP
  • FTP

Servlet support is currently available in several web servers, and will probably start appearing in other types of application servers in the near future. You will use a web server to host the servlets in this class and only deal with the HTTP protocol.

Because HTTP is one of the most common protocols, and because HTML can provide such a rich presentation of information, servlets probably contribute the most to building HTTP based systems.

HTML Support

HTML can provide a rich presentation of information because of its flexibility and the range of content that it can support. Servlets can play a role in creating HTML content. In fact, servlet support for HTML is so common, the javax.servlet.http package is dedicated to supporting HTTP protocol and HTML generation.

Complex web sites often need to provide HTML pages that are tailored for each visitor, or even for each hit. Servlets can be written to process HTML pages and customize them as they are sent to a client. This can be as simple as on the fly substitutions or it can be as complex as compiling a grammar-based description of a page and generating custom HTML.

Inline HTML Generation

Some web servers, such as the Java Web Server (JWS), allow servlet tags to be embedded directly into HTML files. When the server encounters such a tag, it calls the servlet while it is sending the HTML file to the client. This allows a servlet to insert its contribution directly into the outgoing HTML stream.

Server-Side Includes

Another example is on the fly tag processing known as server-side includes (SSI). With SSI, an HTML page can contain special commands that are processed each time a page is requested. Usually a web server requires HTML files that incorporate SSI to use a unique extension, such as .shtml. As an example, if an HTML page (with an .shtml extension) includes the following: <!--#include virtual="/includes/page.html"-->

it would be detected by the web server as a request to perform an inline file include. While server side includes are supported by most web servers, the SSI tags are not standardized.

Servlets are a great way to add server side include processing to a web server. With more and more web servers supporting servlets, it would be possible to write a standard SSI processing servlet and use it on different web servers.

Replacing CGI Scripts

An HTTP servlet is a direct replacement for Common Gateway Interface (CGI) scripts. HTTP servlets are accessed by the user entering a URL in a browser or as the target of an HTML form action. For example, if a user enters the following URL into a browser address field, the browser requests a servlet to send an HTML page with the current time: http://localhost/servlet/DateTimeServlet The DateTimeServlet responds to this request by sending an HTML page to the browser.

Note that these servlets are not restricted to generating web pages; they can perform any other function, such as storing and fetching database information, or opening a socket to another machine.

Installing Servlets

Servlets are not run in the same sense as applets and applications. Servlets provide functionality that extends a server. In order to test a servlet, two steps are required:

  1. Install the servlet in a hosting server
  2. Request a servlet's service via a client request

There are many web servers that support servlets. It is beyond the scope of this course to cover the different ways to install servlets in each server. This course examines the JSDK's servletrunner utility and the JWS.

Temporary versus Permanent Servlets

Servlets can be started and stopped for each client request, or they can be started as the web server is started and kept alive until the server is shut down. Temporary servlets are loaded on demand and offer a good way to conserve resources in the server for less-used functions.

Permanent servlets are loaded when the server is started, and live until the server is shutdown. Servlets are installed as permanent extensions to a server when their start-up costs are very high (such as establishing a connection with a DBMS), when they offer permanent server-side functionality (such as an RMI service), or when they must respond as fast as possible to client requests.

There is no special code necessary to make a servlet temporary or permanent; this is a function of the server configuration.

Because servlets can be loaded when a web server starts, they can use this auto-loading mechanism to provide easier loading of server-side Java programs. These programs can then provide functionality that is totally unique and independent of the web server. For example, a servlet could provide R-based services (rlogin, rsh, ...) through TCP/IP ports while using the servlet request/response protocol to present and process HTML pages used to manage the servlet.

Using servletrunner

For both JDK 1.1 and the Java 2 platform, you need to install the Java Servlet Development Kit (JSDK). To use servletrunner, make sure your PATH environment variable points to its directory. For the JSDK 2.0 installed with all default options, that location is: c:/jsdk2.0/bin on a Windows platform.

To make sure that servletrunner has access to the Java servlet packages, check that your CLASSPATH environment variable is pointing to the correct JAR file, c:/jsdk2.0/lib/jsdk.jar on a Windows platform. With the Java 2 platform, instead of modifying the CLASSPATH, it is easier to just copy the JAR file to the ext directory under the Java runtine environment. This treats the servlet packages as standard extensions.

With the environment set up, run the servletrunner program from the command line. The parameters are:

Usage: servletrunner [options]
Options:
  -p port     the port number to listen on
  -b backlog  the listen backlog
  -m max      maximum number of connection handlers
  -t timeout  connection timeout in milliseconds
  -d dir      servlet directory
  -s filename servlet property file name

The most common way to run this utility is to move to the directory that contains your servlets and run servletrunner from that location. However, that doesn't automatically configure the tool to load the servlets from the current directory.

Magercise

 

  1. Hosting with servletrunner
Using Java Web Server

Sun's Java Web Server (JWS) is a full featured product. For servlet developers, a nice feature is its ability to detect when a servlet has been updated. It detects when new class files have been copied to the appropriate servlet directory and, if necessary, automatically reloads any running servlets.

The JWS can be installed as a service under Windows NT. While this makes it convenient for running a production server, it is not recommended for servlet development work. Under Windows 95, there are no OS services, so the command line start-up is your only option.

To run JWS from the c:/JavaWebServer1.1/bin directory, type in the httpd command. This starts the server in a console window. No further display is shown in the console unless a servlet executes a System.out.println() statement.

Servlets are installed by moving them to the c:/JavaWebServer1.1/servlets directory. As mentioned, JWS detects when servlets have been added to this directory. Although you can use the JWS management applet to tailor the servlet installation, this is generally not advised except for production server installations.

To shut down the JWS, press <Control>+C in the command window. The server prints a message to the console when it has finished shutting down.

Magercise

 

  1. Hosting with the Java Web Server

Servlet API

The Java Servlet API defines the interface between servlets and servers. This API is packaged as a standard extension to the JDK under javax:

The API provides support in four categories:

The Servlet Life Cycle

Servlets run on the web server platform as part of the same process as the web server itself. The web server is responsible for initializing, invoking, and destroying each servlet instance.

A web server communicates with a servlet through a simple interface, javax.servlet.Servlet. This interface consists of three main methods:

and two ancillary methods:

You may notice a similarity between this interface and that of Java applets. This is by design! Servlets are to web servers what applets are to web browsers.An applet runs in a web browser, performing actions it requests through a specific interface. A servlet does the same, running in the web server.

The init() Method

When a servlet is first loaded, its init() method is invoked. This allows the servlet to per form any setup processing such as opening files or establishing connections to their servers. If a servlet has been permanently installed in a server, it loads when the server starts to run. Otherwise, the server activates a servlet when it receives the first client request for the services provided by the servlet.

The init() method is guaranteed to finish before any other calls are made to the servlet--such as a call to the service() method. Note that init() will only be called once; it will not be called again unless the servlet has been unloaded and then reloaded by the server.

The init() method takes one argument, a reference to a ServletConfig object which provides initialization arguments for the servlet. This object has a method getServletContext() that returns a ServletContext object containing information about the servlet's environment (see the discussion on Servlet Initialization Context below).

The service() Method

The service() method is the heart of the servlet. Each request message from a client results in a single call to the servlet's service() method. The service() method reads the request and produces the response message from its two parameters:

  • A ServletRequest object with data from the client. The data consists of name/value pairs of parameters and an InputStream. Several methods are provided that return the client's parameter information. The InputStream from the client can be obtained via the getInputStream() method. This method returns a ServletInputStream, which can be used to get additional data from the client. If you are interested in processing character-level data instead of byte-level data, you can get a BufferedReader instead with getReader().

     

  • A ServletResponse represents the servlet's reply back to the client. When preparing a response, the method setContentType() is called first to set the MIME type of the reply. Next, the method getOutputStream() or getWriter() can be used to obtain a ServletOutputStream or PrintWriter, respectively, to send data back to the client.

As you can see, there are two ways for a client to send information to a servlet. The first is to send parameter values and the second is to send information via the InputStream (or Reader). Parameter values can be embedded into a URL. How this is done is discussed below. How the parameter values are read by the servlet is discussed later.

The service() method's job is conceptually simple--it creates a response for each client request sent to it from the host server. However, it is important to realize that there can be multiple service requests being processed at once. If your service method requires any outside resources, such as files, databases, or some external data, you must ensure that resource access is thread-safe. Making your servlets thread-safe is discussed in a later section of this course.

The destroy() Method

 

The destroy() method is called to allow your servlet to clean up any resources (such as open files or database connections) before the servlet is unloaded. If you do not require any clean-up operations, this can be an empty method.

The server waits to call the destroy() method until either all service calls are complete, or a certain amount of time has passed. This means that the destroy() method can be called while some longer-running service() methods are still running. It is important that you write your destroy() method to avoid closing any necessary resources until all service() calls have completed.

Sample Servlet

The code below implements a simple servlet that returns a static HTML page to a browser. This example fully implements the Servlet interface.

import java.io.*;
import javax.servlet.*;
public class SampleServlet implements Servlet {
  private ServletConfig config;

  public void init (ServletConfig config)
    throws ServletException {
    this.config = config;
  }

  public void destroy() {} // do nothing
  
  public ServletConfig getServletConfig() {
    return config;
  }
  
  public String getServletInfo() {
    return "A Simple Servlet";
  }
  
  public void service (ServletRequest req,
    ServletResponse res 
  ) throws ServletException, IOException  {
    res.setContentType( "text/html" );
    PrintWriter out = res.getWriter();
    out.println( "<html>" );
    out.println( "<head>" );
    out.println( "<title>A Sample Servlet</title>" );
    out.println( "</head>" );
    out.println( "<body>" );
    out.println( "<h1>A Sample Servlet</h1>" );
    out.println( "</body>" );
    out.println( "</html>" );
    out.close();
  }
}

Servlet Context

A servlet lives and dies within the bounds of the server process. To understand its operating environment, a servlet can get information about its environment at different times. Servlet initialization information is available during servlet start-up; information about the hosting server is available at any time; and each service request can contain specific contextual information.

Servlet Initialization Information

Initialization information is passed to the servlet via the ServletConfig parameter of the init() method. Each web server provides its own way to pass initialization information to a servlet. With the JWS, if a servlet class DatePrintServlet takes an initialization argument timezone, you would define the following properties in a servlets.properties file:

  servlet.dateprinter.code=DatePrinterServlet
  servlet.dateprinter.timezone=PST
or this information could be supplied through a GUI administration tool.

The timezone information would be accessed by the servlet with the following code:

  String timezone;
  public void init(ServletConfig config) {
    timeZone = config.getInitParameter("timezone");
  }

An Enumeration of all initialization parameters is available to the servlet via the getInitParameterNames() method.

Server Context Information

Server context information is available at any time through the ServletContext object. A servlet can obtain this object by calling the getServletContext() method on the ServletConfig object. Remember that this was passed to the servlet during the initialization phase. A well written init() method saves the reference in a private variable.

The ServletContext interface defines several methods. These are outlined below.

getAttribute()An extensible way to get information about a server via attribute name/value pairs. This is server specific.
getMimeType()Returns the MIME type of a given file.
getRealPath()This method translates a relative or virtual path to a new path relative to the server's HTML documentation root location.
getServerInfo()Returns the name and version of the network service under which the servlet is running.
getServlet() Returns a Servlet object of a given name. Useful when you want to access the services of other servlets.
getServletNames()Returns an enumeration of servlet names available in the current namespace.
log()Writes information to a servlet log file. The log file name and format are server specific.

The following example code shows how a servlet uses the host server to write a message to a servlet log when it initializes:

  private ServletConfig config;
  public void init(ServletConfig config) {
    // Store config in an instance variable
    this.config = config;
    ServletContext sc = config.getServletContext();
    sc.log( "Started OK!" );
  }

Servlet Context During a Service Request

Each service request can contain information in the form of name/value parameter pairs, as a ServletInputStream, or a BufferedReader. This information is available from the ServletRequest object that is passed to the service() method.

The following code shows how to get service-time information:

  BufferedReader reader;
  String         param1;
  String         param2;
  public void service (
      ServletRequest  req,
      ServletResponse res) {

    reader = req.getReader();
    param1 = req.getParameter("First");
    param2 = req.getParameter("Second");
  }

There are additional pieces of information available to the servlet through ServletRequest. These are shown in the following table.

getAttribute()Returns value of a named attribute for this request.
getContentLength()Size of request, if known.
getContentType()Returns MIME type of the request message body.
getInputStream()Returns an InputStream for reading binary data from the body of the request message.
getParameterNames()Returns an array of strings with the names of all parameters.
getParameterValues()Returns an array of strings for a specific parameter name.
getProtocol()Returns the protocol and version for the request as a string of the form <protocol>/<major version>.<minor version>.
getReader()Returns a BufferedReader to get the text from the body of the request message.
getRealPath()Returns actual path for a specified virtual path.
getRemoteAddr()IP address of the client machine sending this request.
getRemoteHost()Host name of the client machine that sent this request.
getScheme()Returns the scheme used in the URL for this request (for example, https, http, ftp, etc.).
getServerName()Name of the host server that received this request.
getServerPort()Returns the port number used to receive this request.

The following Magercise shows you how to extract parameters from a service request.

Magercise

 

  1. Accessing Servlet Service-Time Parameters
Utility Classes

There are several utilities provided in the Servlet API. The first is the interface javax.servlet.SingleThreadModel that can make it easier to write simple servlets. If a servlet implements this marker interface, the hosting server knows that it should never call the servlet's service() method while it is processing a request. That is, the server processes all service requests within a single thread.

While this makes it easier to write a servlet, this can impede performance. A full discussion of this issue is located later in this course.

Two exception classes are included in the Servlet API. The exception javax.servlet.ServletException can be used when there is a general failure in the servlet. This notifies the hosting server that there is a problem.

The exception javax.servlet.UnavailableException indicates that a servlet is unavailable. Servlets can report this exception at any time. There are two types of unavailability:

  • Permanent. The servlet is unable to function until an administrator takes some action. In this state, a servlet should write a log entry with a problem report and possible resolutions.

     

  • Temporary. The servlet encountered a (potentially) temporary problem, such as a full disk, failed server, etc. The problem can correct itself with time or may require operator intervention.
HTTP Support

Servlets that use the HTTP protocol are very common. It should not be a surprise that there is specific help for servlet developers who write them. Support for handling the HTTP protocol is provided in the package javax.servlet.http. Before looking at this package, take a look at the HTTP protocol itself.

HTTP stands for the HyperText Transfer Protocol. It defines a protocol used by web browsers and servers to communicate with each other. The protocol defines a set of text-based request messages called HTTP methods. (Note: The HTTP specification calls these HTTP methods; do not confuse this term with Java methods. Think of HTTP methods as messages requesting a certain type of response). The HTTP methods include:

  • GET
  • HEAD
  • POST
  • PUT
  • DELETE
  • TRACE
  • CONNECT
  • OPTIONS

For this course, you will only need to look at only three of these methods: GET, HEAD, and POST.

The HTTP GET Method

 

The HTTP GET method requests information from a web server. This information could be a file, output from a device on the server, or output from a program (such as a servlet or CGI script).

An HTTP GET request takes the form:

  GET URL <http version>
  Host: <target host>

in addition to several other lines of information.

For example, the following HTTP GET message is requesting the home page from the MageLang web site:

  GET / HTTP/1.1
  Connection: Keep-Alive
  User-Agent: Mozilla/4.0 (
   compatible; 
   MSIE 4.01; 
   Windows NT)
  Host: www.magelang.com
  Accept: image/gif, image/x-xbitmap, 
   image/jpeg, image/pjpeg

On most web servers, servlets are accessed via URLs that start with /servlet/. The following HTTP GET method is requesting the servlet MyServlet on the host www.magelang.com:

  GET /servlet/MyServlet?name=Scott&
    company=MageLang%20Institute HTTP/1.1
  Connection: Keep-Alive
  User-Agent: Mozilla/4.0 (
   compatible; 
   MSIE 4.01; 
   Windows NT)
  Host: www.magelang.com
  Accept: image/gif, image/x-xbitmap, 
   image/jpeg, image/pjpeg

The URL in this GET request invokes the servlet called MyServlet and contains two parameters, name and company. Each parameter is a name/value pair following the format name=value. The parameters are specified by following the servlet name with a question mark ('?'), with each parameter separated by an ampersand ('&').

Note the use of %20 in the company's value. A space would signal the end of the URL in the GET request line, so it must be "URL encoded", or replaced with %20 instead. As you will see later, servlet developers do not need to worry about this encoding as it will be automatically decoded by the HttpServletRequest class.

HTTP GET requests have an important limitation. Most web servers limit how much data can be passed as part of the URL name (usually a few hundred bytes.) If more data must be passed between the client and the server, the HTTP POST method should be used instead.

It is important to note that the server's handling of a GET method is expected to be safe and idempotent. This means that a GET method will not cause any side effects and that it can be executed repeatedly.

When a server replies to an HTTP GET request, it sends an HTTP response message back. The header of an HTTP response looks like the following:

  HTTP/1.1 200 Document follows
  Date: Tue, 14 Apr 1997 09:25:19 PST
  Server: JWS/1.1
  Last-modified: Mon, 17 Jun 1996 21:53:08 GMT
  Content-type: text/html
  Content-length: 4435

  <4435 bytes worth of data -- the document body>

The HEAD Method

 

The HTTP HEAD method is very similar to the HTTP GET method. The request looks exactly the same as the GET request (except the word HEAD is used instead of GET), but the server only returns the header information.

HEAD is often used to check the following:

  • The last-modified date of a document on the server for caching purposes
  • The size of a document before downloading (so the browser can present progress information)
  • The server type, allowing the client to customize requests for that server
  • The type of the requested document, so the client can be sure it supports it

Note that HEAD, like GET, is expected to be safe and idempotent.

The POST Method

An HTTP POST request allows a client to send data to the server. This can be used for several purposes, such as

  • Posting information to a newsgroup
  • Adding entries to a web site's guest book
  • Passing more information than a GET request allows

Pay special attention to the third bullet above. The HTTP GET request passes all its arguments as part of the URL. Many web servers have a limit to how much data they can accept as part of the URL. The POST method passes all of its parameter data in an input stream, removing this limit.

A typical POST request might be as follows:

  POST /servlet/MyServlet HTTP/1.1
  User-Agent: Mozilla/4.0 (
   compatible; 
   MSIE 4.01; 
   Windows NT)
  Host: www.magelang.com
  Accept: image/gif, image/x-xbitmap, 
   image/jpeg, image/pjpeg, */
  Content-type: application/x-www-form-urlencoded
  Content-length: 39

  name=Scott&company=MageLang%20Institute

Note the blank line--this signals the end of the POST request header and the beginning of the extended information.

Unlike the GET method, POST is not expected to be safe nor idempotent; it can perform modifications to data, and it is not required to be repeatable.

HTTP Support Classes

Now that you have been introduced to the HTTP protocol, consider how the javax.servlet.http package helps you write HTTP servlets. The abstract class javax.servlet.http.HttpServlet provides an implementation of the javax.servlet.Servlet interface and includes a lot of helpful default functionality. The easiest way to write an HTTP servlet is to extend HttpServlet and add your own custom processing.

The class HttpServlet provides an implementation of the service() method that dispatches the HTTP messages to one of several special methods. These methods are:

and correspond directly with the HTTP protocol methods.

As shown in the following diagram, the service() method interprets each HTTP method and determines if it is an HTTP GET, HTTP POST, HTTP HEAD, or other HTTP protocol method:

The class HttpServlet is actually rather intelligent. Not only does it dispatch HTTP requests, it detects which methods are overridden in a subclass and can report back to a client on the capabilities of the server. (Simply by overriding the doGet() method causes the class to respond to an HTTP OPTIONS method with information that GET, HEAD, TRACE, and OPTIONS are all supported. These capabilities are in fact all supported by the class's code).

In another example of the support HttpServlet provides, if the doGet() method is overridden, there is an automatic response generated for the HTTP HEAD method. (Since the response to an HTTP HEAD method is identical to an HTTP GET method--minus the body of the message--the HttpServlet class can generate an appropriate response to an HTTP HEAD request from the reply sent back from the doGet() method). As you might expect, if you need more precise control, you can always override the doHead() method and provide a custom response.

Using the HTTP Support Classes

When using the HTTP support classes, you generally create a new servlet that extends HttpServlet and overrides either doGet() or doPost(), or possibly both. Other methods can be overridden to get more fine-grained control.

The HTTP processing methods are passed two parameters, an HttpServletRequest object and an HttpServletResponse object. The HttpServletRequest class has several convenience methods to help parse the request, or you can parse it yourself by simply reading the text of the request.

A servlet's doGet() method should

  • Read request data, such as input parameters
  • Set response headers (length, type, and encoding)
  • Write the response data

It is important to note that the handling of a GET method is expected to be safe and idempotent.

  • Handing is considered safe if it does not have any side effects for which users are held responsible, such as charging them for the access or storing data.
  • Handling is considered idempotent if it can safely be repeated. This allows a client to repeat a GET request without penalty.

Think of it this way: GET should be "looking without touching." If you require processing that has side effects, you should use another HTTP method, such as POST.

A servlet's doPost() method should be overridden when you need to process an HTML form posting or to handle a large amount of data being sent by a client. HTTP POST method handling is discussed in detail later.

HEAD requests are processed by using the doGet() method of an HttpServlet. You could simply implement doGet() and be done with it; any document data that you write to the response output stream will not be returned to the client. A more efficient implementation, however, would check to see if the request was a GET or HEAD request, and if a HEAD request, not write the data to the response output stream.

Summary

The Java Servlet API is a standard extension. This means that there is an explicit definition of servlet interfaces, but it is not part of the Java Development Kit (JDK) 1.1 or the Java 2 platform. Instead, the servlet classes are delivered with the Java Servlet Development Kit (JSDK) version 2.0 from Sun (http://java.sun.com/products/servlet/). This JSDK version is intended for use with both JDK 1.1 and the Java 2 platform. There are a few significant differences between JSDK 2.0 and JSDK 1.0. See below for details. If you are using a version of JSDK earlier than 2.0, it is recommended that you upgrade to JSDK 2.0.

Servlet support currently spans two packages:

javax.servlet: General Servlet Support
ServletAn interface that defines communication between a web server and a servlet. This interface defines the init(), service(), and destroy() methods (and a few others).
ServletConfigAn interface that describes the configuration parameters for a servlet. This is passed to the servlet when the web server calls its init() method. Note that the servlet should save the reference to the ServletConfig object, and define a getServletConfig() method to return it when asked. This interface defines how to get the initialization parameters for the servlet and the context under which the servlet is running.
ServletContextAn interface that describes how a servlet can get information about the server in which it is running. It can be retrieved via the getServletContext() method of the ServletConfig object.
ServletRequestAn interface that describes how to get information about a client request.
ServletResponseAn interface that describes how to pass information back to the client.
GenericServletA base servlet implementation. It takes care of saving the ServletConfig object reference, and provides several methods that delegate their functionality to the ServletConfig object. It also provides a dummy implementation for init() and destroy().
ServletInputStreamA subclass of InputStream used for reading the data part of a client's request. It adds a readLine() method for convenience.
ServletOutputStreamAn OutputStream to which responses for the client are written.
ServletExceptionShould be thrown when a servlet problem is encountered.
UnavailableExceptionShould be thrown when the servlet is unavailable for some reason.

javax.servlet.http: Support for HTTP Servlets
HttpServletRequestA subclass of ServletRequest that defines several methods that parse HTTP request headers.
HttpServletResponseA subclass of ServletResponse that provides access and interpretation of HTTP status codes and header information.
HttpServletA subclass of GenericServlet that provides automatic separation of HTTP request by method type. For example, an HTTP GET request will be processed by the service() method and passed to a doGet() method.
HttpUtilsA class that provides assistance for parsing HTTP GET and POST requests.

Servlet Examples

 

Now for an in-depth look at several servlets. These examples include:

Generating Inline Content

Sometimes a web page needs only a small piece of information that is customized at runtime. The remainder of a page can be static information. To substitute only small amounts of information, some web servers support a concept known as server-side includes, or SSI.

If it supports SSI, the web server designates a special file extension (usually .shtml) which tells the server that it should look for SSI tags in the requested file. The JWS defines a special SSI tag called the <servlet> tag, for example:

  <servlet code="DatePrintServlet">
    <param name=timezone value=pst>
  </servlet>

This tag causes the invoking of a servlet named DatePrintServlet to generate some in-line content.

SSI and servlets allow an HTML page designer to write a skeleton for a page, using servlets to fill in sections of it, rather than require the servlet to generate the entire page. This is very useful for features like page-hit counters and other small pieces of functionality.

The DatePrintServlet servlet works just like a regular servlet except that it is designed to provide a very small response and not a complete HTML page. The output MIME type gets set to "text/plain" and not "text/html".

Keep in mind that the syntax of server-side includes, if they are even supported, may vary greatly from one web server to another.

In the following Magercise you create the DatePrintServlet and see how to use it in an HTML page.

Magercise

 

  1. Generating In-line Content
Processing HTTP Post Requests

HTTP POST method processing differs from HTTP GET method processing in several ways. First, because POST is expected to modify data on the server, there can be a need to safely handle updates coming from multiple clients at the same time. Second, because the size of the information stream sent by the client can be very large, the doPost() method must open an InputStream (or Reader) from the client to get any of the information. HTTP POST does not support sending parameters encoded inside of the URL as does the HTTP GET method.

The problem of supporting simultaneous updates from multiple clients has been solved by database systems (DBMSs); unfortunately the HTTP protocol does not work well with database systems. This is because DBMSs need to maintain a persistent connection between a client and the DBMS to determine which client is trying to update the data.

The HTTP protocol does not support this type of a connection as it is a message based, stateless protocol. Solving this problem is not easy and never elegant! Fortunately, the Servlet API defines a means to track client/server sessions. This is covered in the Maintaining Session Information section later in this course. Without session management tracking, one can resort to several different strategies. They all involve writing data to the client in hidden fields which is then sent back to the server. The simplest way to handle updates is to use an optimistic locking scheme based on date/time stamps. One can use a single date/time stamp for a whole form of data, or one could use separate date/time stamps for each "row" of information.

Once the update strategy has been selected, capturing the data sent to the server via an HTTP POST method is straightforward. Information from the HTML form is sent as a series of parameters (name/value pairs) in the InputStream object. The HttpUtils class contains a method parsePostData() that accepts the raw InputStream from the client and return a Hashtable with the parameter information already processed. A really nice feature is that if a parameter of a given name has multiple values (such is the case for a column name with multiple rows), then this information can be retrieved from the Hashtable as an array of type String.

In the following Magercise, you will be given skeleton code that implements a pair of servlets that display data in a browser as an editable HTML form. The structure of the data is kept separate from the actual data. This makes it easy to modify this code to run against arbitrary tables from a JDBC-connected database.

Magercise

 

  1. Posting and Processing HTML Forms
Using Cookies

For those unfamiliar with cookies, a cookie is a named piece of data maintained by a browser, normally for session management. Since HTTP connections are stateless, you can use a cookie to store persistent information accross multiple HTTP connections. The Cookie class is where all the "magic" is done. The HttpSession class, described next, is actually easier to use. However, it doesn't support retaining the information across multiple browser sessions.

To save cookie information you need to create a Cookie, set the content type of the HttpServletResponse response, add the cookie to the response, and then send the output. You must add the cookie after setting the content type, but before sending the output, as the cookie is sent back as part of the HTTP response header.

  private static final String SUM_KEY = "sum";
  ...
  int sum = ...; // get old value and add to it
  Cookie theCookie = 
    new Cookie (SUM_KEY, Integer.toString(sum));
  response.setContentType("text/html");
  response.addCookie(theCookie);

It is necessary to remember that all cookie data are strings. You must convert information like int data to a String object. By default, the cookie lives for the life of the browser session. To enable a cookie to live longer, you must call the setMaxAge(interval) method. When positive, this allows you to set the number of seconds a cookie exists. A negative setting is the default and destroys the cookie when the browser exits. A zero setting immediately deletes the cookie.

Retrieving cookie data is a little awkward. You cannot ask for the cookie with a specific key. You must ask for all cookies and find the specific one you are interested in. And, it is possible that multiple cookies could have the same name, so just finding the first setting is not always sufficient. The following code finds the setting of a single-valued cookie:

  int sum = 0;
  Cookie theCookie = null;
  Cookie cookies[] = request.getCookies();
  if (cookies != null) {
    for(int i=0, n=cookies.length; i < n; i++) {
      theCookie = cookies[i];
      if (theCookie.getName().equals(SUM_KEY)) {
        try {
          sum = Integer.parseInt(theCookie.getValue());
        } catch (NumberFormatException ignored) {
          sum = 0;
        }
        break;
      }
    }
  }

The complete code example shown above is available for testing.

Maintaining Session Information

A session is a continuous connection from the same browser over a fixed period of time. (This time is usually configurable from the web server. For the JWS, the default is 30 minutes.) Through the implicit use of browser cookies, HTTP servlets allow you to maintain session information with the HttpSession class. The HttpServletRequest provides the current session with the getSession(boolean) method. If the boolean parameter is true, a new session will be created when a new session is detected. This is, normally, the desired behavior. In the event the parameter is false, then the method returns null if a new session is detected.

  public void doGet (HttpServletRequest request, 
      HttpServletResponse response) 
      throws ServletException, IOException {
    HttpSession session = request.getSession(true);
    // ...

Once you have access to an HttpSession, you can maintain a collection of key-value-paired information, for storing any sort of session-specific data. You automatically have access to the creation time of the session with getCreationTime() and the last accessed time with getLastAccessedTime(), which describes the time the last servlet request was sent for this session.

To store session-specific information, you use the putValue(key, value) method. To retrieve the information, you ask the session with getValue(key). The following example demonstrates this, by continually summing up the integer value of the Addend parameter. In the event the value is not an integer, the number of errors are also counted.

  private static final String SUM_KEY = 
    "session.sum";
  private static final String ERROR_KEY = 
    "session.errors";
  Integer sum = (Integer) session.getValue(SUM_KEY);
  int ival = 0;
  if (sum != null) {
    ival = sum.intValue();
  }
  try {
    String addendString = 
    request.getParameter("Addend");
    int addend = Integer.parseInt (addendString);
    sum = new Integer(ival + addend);
    session.putValue (SUM_KEY, sum);
  } catch (NumberFormatException e) {
    Integer errorCount = 
      (Integer)session.getValue(ERROR_KEY);
    if (errorCount == null) {
      errorCount = new Integer(1);
    } else {
      errorCount = new Integer(errorCount.intValue()+1);
    }
    session.putValue (ERROR_KEY, errorCount);
  }

As with all servlets, once you've performed the necessary operations, you need to generate some output. If you are using sessions, it is necessary to request the session with HttpServletRequest.getSession() before generating any output.

  response.setContentType("text/html");
  PrintWriter out = response.getWriter();
  out.println("<html>" +
    "<head><title>Session Information</title></head>" +
    "<body bgcolor=/"#FFFFFF/">" +
    "<h1>Session Information</h1><table>");
  out.println ("<tr><td>Identifier</td>");
  out.println ("<td>" + session.getId() + "</td></tr>");
  out.println ("<tr><td>Created</td>");
  out.println ("<td>" + new Date(
    session.getCreationTime()) + "</td></tr>");
  out.println ("<tr><td>Last Accessed</td>");
  out.println ("<td>" + new Date(
    session.getLastAccessedTime()) + "</td></tr>");
  out.println ("<tr><td>New Session?</td>");
  out.println ("<td>" + session.isNew() + "</td></tr>");
  String names[] = session.getValueNames();
  for (int i=0, n=names.length; i<n; i++) {
    out.println ("<tr><td>" + names[i] + "</td>");
    out.println ("<td>" + session.getValue (names[i])
      + "</td></tr>");
  }
  out.println("</table></center></body></html>");
  out.close();

The complete code example shown above is available for testing. One thing not demonstrated in the example is the ability to end a session, where the next call to request.getSession(true) returns a different session. This is done with a call to invalidate().

In the event a user has browser cookies disabled, you can encode the session ID within the HttpServletResponse by calling its encodeUrl() method.

Connecting to Databases

It is very common to have servlets connect to databases through JDBC. This allows you to better control access to the database by only permitting the middle-tier to communicate with the database. If your database server includes sufficient simultanious connection licenses, you can even setup database connections once, when the servlet is initialized, and pool the connections between all the different service requests.

The following demonstrates sharing a single Connection between all service requests. To find out how many simultaneous connections the driver supports, you can ask its DatabaseMetaData and then create a pool of Connection objects to share between service requests.

  • In the init() method connect to the database.
    Connection con = null;
    public void init (ServletConfig cfg)
      throws ServletException {
      super.init (cfg);
      // Load driver
      String name = cfg.getInitParameter("driver");
      Class.forName(name);
      // Get Connection
      con = DriverManager.getConnection (urlString);
    }
    

  • In the doGet() method retrieve database information.
    public void doGet (HttpServletRequest request, 
        HttpServletResponse response) 
        throws ServletException, IOException {
      response.setContentType("text/html");
    
      // Have browser ignore cache - force reload
      response.setHeader ("Expires", 
        "Mon, 01 Jan 1990 00:00:00 GMT");
    
      Statement stmt = null;
      ResultSet result = null;
    
      try {
        // Submit query
        stmt = con.createStatement();
        result = stmt.executeQuery (
          "SELECT programmer, cups " + 
          "FROM JoltData ORDER BY cups DESC;");
    
        // Create output
        PrintWriter out = response.getWriter();
        while(result.next()) {
          // Generate output from ResultSet
        }
      } finally {
        if (result != null) {
          result.close();
        }
        if (stmt != null) {
          stmt.close();
        }
      }
      out.flush();
      out.close();
    }
    

  • In the destroy() method disconnect from the database.
    public void destroy() {
      super.destroy();
      con.close();
    }
    

It is not good practice to leave a database connection permanently open, so this servlet should not be installed as a permanent servlet. Having it as a temporary servlet that closes itself down after a predefined period of inactivity allows the sharing of the database connection with requests that coincide, reducing the cost of each request.

You can also save some information in the HttpSession to possible page through the result set.

Security Issues

 

As with Java applets, Java servlets have security issues to worry about, too.

The Servlet Sandbox

A servlet can originate from several sources. A webmaster may have written it; a user may have written it; it may have been bought as part of a third-party package or downloaded from another web site.

Based on the source of the servlet, a certain level of trust should be associated with that servlet. Some web servers provide a means to associate different levels of trust with different servlets. This concept is similar to how web browsers control applets, and is known as "sandboxing".

A servlet sandbox is an area where servlets are given restricted authority on the server. They may not have access to the file system or network, or they may have been granted a more trusted status. It is up to the web server administrator to decide which servlets are granted this status. Note that a fully trusted servlet has full access to the server's file system and networking capabilities. It could even perform a System.exit(), stopping the web server...

Access Control Lists (ACLs)

Many web servers allow you to restrict access to certain web pages and servlets via access control lists (ACLs). An ACL is a list of users who are allowed to perform a specific function in the server. The list specifies:

  • What kind of access is allowed
  • What object the access applies to
  • Which users are granted access

Each web server has its own means of specifying an ACL, but in general, a list of users is registered on the server, and those user names are used in an ACL. Some servers also allow you to add users to logical groups, so you can grant access to a group of users without specifying all of them explicitly in the ACL.

ACLs are extremely important, as some servlets can present or modify sensitive data and should be tightly controlled, while others only present public knowledge and do not need to be controlled.

Threading Issues

A web server can call a servlet's service() method for several requests at once. This brings up the issue of thread safety in servlets.

But first consider what you do not need to worry about: a servlet's init() method. The init() method will only be called once for the duration of the time that a servlet is loaded. The web server calls init() when loading, and will not call it again unless the servlet has been unloaded and reloaded. In addition, the service() method or destroy() method will not be called until the init() method has completed its processing.

Things get more interesting when you consider the service() method. The service() method can be called by the web server for multiple clients at the same time. (With the JSDK 2.0, you can tag a servlet with the SingleThreadModel interface. This results in each call to service() being handled serially. Shared resources, such as files and databases, can still have concurrency issues to handle.)

If your service() method uses outside resources, such as instance data from the servlet object, files, or databases, you need to carefully examine what might happen if multiple calls are made to service() at the same time. For example, suppose you had defined a counter in your servlet class that keeps track of how many service() method invocations are currently running:

  private int counter = 0;

Next, suppose that your service() method contained the following code:

  int myNumber = counter + 1;  // line 1
  counter = myNumber;          // line 2

  // rest of the code in the service() method

  counter = counter - 1;

What would happen if two service() methods were running at the same time, and both executed line 1 before either executed line 2? Both would have the same value for myNumber, and the counter would not be properly updated.

For this situation, the answer might be to synchronize the access to the counter variable:

  synchronized(this) {
    myNumber = counter + 1;
    counter = myNumber;
  }

  // rest of code in the service() method

  synchronized(this) {
    counter = counter - 1 ;
  }

This ensures that the counter access code is executed only one thread at a time.

There are several issues that can arise with multi-threaded execution, such as deadlocks and coordinated interactions. There are several good sources of information on threads, including Doug Lea's book Concurrent Programming in Java.

JSDK 1.0 and JSDK 2.0

The Java Servlet Development Kit (JSDK) provides servlet support for JDK 1.1 and Java 2 platform developers.

JSDK 1.0 was the initial release of the development kit. Everything worked fine, but there were some minor areas that needed improvement. The JSDK 2.0 release incorporates these improvements. The changes between JSDK 1.0 and JSDK 2.0 are primarily the addition of new classes. In addition, there is also one deprecated methods. Because some web servers still provide servlet support that complies with the JSDK 1.0 API definitions, you need to be careful about upgrading to the new JSDK.

New Servlet Features in JSDK 2.0

JSDK 2.0 adds the following servlet support:

  • The interface SingleThreadModel indicates to the server that only one thread can call the service() method at a time.
  • Reader and Writer access from ServletRequest and ServletResponse
  • Several HTTP session classes that can be used to provide state information that persists over multiple connections and requests between an HTTP client and an HTTP server.
  • Cookie support is now part of the standard servlet extension.
  • Several new HTTP response constants have been added to HttpServletResponse
  • Delegation of DELETE, OPTIONS, PUT, and TRACE to appropriate methods in HttpServlet

JSDK 2.0 deprecated one method:

For More Information

Interest and support for servlets is exploding. Here are some links to help you keep up to date:

Java Servlet API说明文档 绪言 这是一份关于2.1版JavaServletAPI的说明文档,作为对这本文档的补充,你可以到http://java.sun.com/products/servlet/index.html下面下载Javadoc格式的文档。 谁需要读这份文档 这份文档描述了JavaServletAPI的最新版本2.1版。所以,这本书对于Servlet的开发者及servlet引擎的开发者同样适用。 JavaServletAPI的组成 JavaServletAPI由两个软件包组成:一个是对应HTTP的软件包,另一个是不对应HTTP的通用的软件包。这两个软件包的同时存在使得JavaServletAPI能够适应将来的其他请求-响应的协议。 这份文档以及刚才提及的Javadoc格式的文档都描述了这两个软件包,Javadoc格式的文档还描述了你应该如何使用这两个软件包中的所有方法。 有关规范 你也许对下面的这些Internet规范感兴趣,这些规范将直接影响到ServletAPI的发展和执行。你可以从http://info.internet.isi.edu/7c/in-notes/rfc/.cache找到下面提到的所有这些RFC规范。 RFC1738统一资源定位器(URL) RFC1808相关统一资源定位器 RFC1945超文本传输协议--HTTP/1.0 RFC2045多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第一部分:Internet信息体格式 RFC2046多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第二部分:媒体类型 RFC2047多用途网际邮件扩充协议(MIME)(多用途Internet邮件扩展)第三部分:信息标题扩展用于非ASCII文本 RFC2048多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第四部分:注册步骤 RFC2049多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第五部分:一致性标准和例子 RFC2068超文本传输协议--HTTP/1.1 RFC2069一个扩展HTTP:摘要访问鉴定 RFC2109HTTP状态管理机制 RFC2145HTTP版本号的使用和解释 RFC2324超文本CoffeePot控制协议(HTCPCP/1.0) 万维网协会(http://www.w3.org)管理着这些协议的规范和执行。 有关JavaServlets JavaTMservlets是一个不受平台约束的Java小程序,它可以被用来通过多种方法扩充一个Web服务器的功能。你可以把Servlet理解成Server上的applets,它被编译成字节码,这样它就可以被动态地载入并用效地扩展主机的处理能力。 Servlet与applets不同的地方是,它不运行在Web浏览器或其他图形化的用户界面上。Servlet通过servlet引擎运行在Web服务器中,以执行请求和响应,请求、响应的典型范例是HTTP协议。 一个客户端程序,可以是一个Web浏览器,或者是非其他的可以连接上Internet的程序,它会访问Web服务器并发出请求。这个请求被运行在Web服务器上的Servlet引擎处理,并返回响应到ServletServlet通过HTTP将这个响应转发到客户端。 在功能上,Servlet与CGI、NSAPI有点类似,但是,与他们不同的是:Servlet具有平台无关性。 JavaServlet概论 Servlet与其他普通的server扩展机制有以下进步: 因为它采用了不同的进程处理模式,所以它比CGI更快。 它使用了许多Web服务器都支持的标准的API。 它继承了Java的所有优势,包括易升级以及平台无关性。 它可以调用Java所提供的大量的API的功能模块。 这份文档说明了JavaServletAPI的类和接口的方法。有关更多的信息,请参看下面的API说明。 Servlet的生命周期 一个Javaservlet具有一个生命周期,这个生命周期定义了一个Servlet如何被载入并被初始化,如何接收请求并作出对请求的响应,如何被从服务中清除。Servlet的生命周期被javax.servlet.Servlet这个接口所定义。 所有的JavaServlet都会直接地或间接地执行javax.servlet.Servlet接口,这样它才能在一个Servlet引擎中运行。Servlet引擎是Web服务器按照JavaServletAPI定制的扩展。Servlet引擎提供网络服务,能够理解MIME请求,并提供一个运行Servlet的容器。 javax.servlet.Servlet接口定义了在Servlet的生命周期中特定时间以及特定顺序被调用的方法。 Servlet的解析和载入 Servlet引擎解析并载入一个Servlet,这个过程可以发生在引擎启动时,需要一个Servlet去响应请求时,以及在此之间的任何时候。 Servlet引擎利用Java类载入工具载入一个ServletServlet引擎可以从一个本地的文件系统、一个远程的文件系统以及网络载入ServletServlet的初始化 Servlet引擎载入Servlet后,Servlet引擎必须对Servlet进行初始化,在这一过程中,你可以读取一些固定存储的数据、初始化JDBC的连接以及建立与其他资源的连接。 在初始化过程中,javax.servlet.Servlet接口的init()方法提供了Servlet的初始化信息。这样,Servlet可以对自己进行配置。 init()方法获得了一个Servlet配置对象(ServletConfig)。这个对象在Servlet引擎中执行,并允许Servlet通过它获处相关参数。这个对象使得Servlet能够访问ServletContext对象。 Servlet处理请求\r Servlet被初始化之后,它已经可以处理来自客户端的请求,每一个来自客户端的请求都被描述成一个ServletRequest对象,Servlet的响应被描述成一个ServletResponse对象。 当客户端发出请求时,Servlet引擎传递给Servlet一个ServletRequest对象和一个ServletResponse对象,这两个对象作为参数传递到service()方法中。 Servlet也可以执行ServletRequest接口和ServletResponse接口。ServletRequest接口使得Servlet有权使用客户端发出的请求。Servlet可以通过ServletInputStream对象读取请求信息。 ServletResponse接口允许Servlet建立响应头和状态代码。通过执行这个接口,Servlet有权使用ServletOutputStream类来向客户端返回数据。 多线程和映射\r 在多线程的环境下,Servlet必须能处理许多同时发生的请求。例外的情况是这个Servlet执行了SingleThreadModel接口,如果是那样的话,Servlet只能同时处理一个请求。 Servlet依照Servlet引擎的映射来响应客户端的请求。一个映射对包括一个Servlet实例以及一个Servlet返回数据的URL,例如:HelloServletwith/hello/index.html。 然而,一个映射可能是由一个URL和许多Servlet实例组成,例如:一个分布式的Servlet引擎可能运行在不止一个的服务器中,这样的话,每一个服务器中都可能有一个Servlet实例,以平衡进程的载入。作为一个Servlet的开发者,你不能假定一个Servlet只有一个实例。 Servlet的卸载 Servlet引擎并不必需保证一个Servlet在任何时候或在服务开启的任何时候都被载入。Servlet引擎可以自由的在任何时候使用或清除一个Servlet。因此,我们不能依赖一个类或实例来存储重要的信息。 当Servlet引擎决定卸载一个Servlet时(例如,如果这个引擎被关闭或者需要让资源),这个引擎必须允许Servlet释放正在使用的资源并存储有关资料。为了完成以上工作,引擎会调用Servlet的destroy()方法。 在卸载一个Servlet之前,Servlet引擎必须等待所有的service()方法完成或超时结束(Servlet引擎会对超时作出定义)。当一个Servlet被卸载时,引擎将不能给Servlet发送任何请求。引擎必须释放Servlet并完成无用存储单元的收集 Servlet映射技术\r 作为一个Servlet引擎的开发者,你必须对于如何映射客户端的请求到Servlet有大量的适应性。这份说明文档不规定映射如何发生。但是,你必须能够自由地运用下面的所有技术: 映射一个Servlet到一个URL 例如,你可以指定一个特殊的Servlet它仅被来自/feedback/index.html的请求调用。 映射一个Servlet到以一个指定的目录名开始的所有URL 例如,你可以映射一个Servlet到/catalog,这样来自/catalog/、/catalog/garden和/catalog/housewares/index.html的请求都会被映射到这个Servlet。但是来自/catalogtwo或/catalog.html的请求没被映射。 映射一个Servlet到所有以一个特定的字段结尾的所有URL 例如,你可以映射一个来自于所有以in.thtml结尾的请求到一个特定的Servlet。 映射一个Servlet到一个特殊的URL/servlet/servlet_name。 例如,如果你建立了一个名叫listattributes的Servlet,你可以通过使用/servlet/listattributes来访问这个Servlet。 通过类名调用Servlet 例如,如果Servlet引擎接收了来自/servlet/com.foo.servlet.MailServlet的请求,Servlet引擎会载入这个com.foo.servlet.MailServlet类,建立实例,并通过这个Servlet来处理请求。 Servlet环境 ServletContext接口定义了一个Servlet环境对象,这个对象定义了一个在Servlet引擎上的Servlet的视图。通过使用这个对象,Servlet可以记录事件、得到资源并得到来自Servlet引擎的类(例如RequestDispatcher对象)。一个Servlet只能运行在一个Servlet环境中,但是不同的Servlet可以在Servlet引擎上有不同的视图。 如果Servlet引擎支持虚拟主机,每个虚拟主机有一个Servlet环境。一个Servlet环境不能在虚拟主机之间共享。 Servlet引擎能够允许一个Servlet环境有它自己的活动范围。 例如,一个Servlet环境是属于bank应用的,它将被映射到/bank目录下。在这种情况下,一个对getContext方法的调用会返回/bank的Servlet环境。 HTTP会话 HTTP是一个没有状态的协议。要建立一个有效的Web服务应用,你必须能够识别一个连续的来自远端的客户机的唯一的请求。随着时间的过去,发展了许多会话跟踪的技术,但是使用起来都比较麻烦。 JavaServletAPI提供了一个简单的接口,通过这个接口,Servlet引擎可以有效地跟踪用户的会话。 建立Session 因为HTTP是一个请求-响应协议,一个会话在客户机加入之前会被认为是一个新的会话。加入的意思是返回会话跟踪信息到服务器中,指出会话已被建立。在客户端加入之前,我们不能判断下一个客户端请求是目前会话的一部分。 在下面的情况下,Session会被认为是新的Session。 客户端的Session在此之前还不知道 客户端选择不加入Session,例如,如果客户端拒绝接收来自服务器的cookie 作为一个Servlet的开发者,你必须决定你的Web应用是否处理客户机不加入或不能加入Session。服务器会在Web服务器或Servlet规定的时间内维持一个Session对象。当Session终止时,服务器会释放Session对象以及所有绑定在Session上的对象。 绑定对象到Session中 如果有助于你处理应用的数据需求,你也许需要绑定对象到Session中,你可以通过一个唯一的名字绑定任何的对象到Session中,这时,你需要使用HttpSession对象。任何绑定到Session上的对象都可以被处理同一会话的Servlet调用。 有些对象可能需要你知道什么时候会被放置到Session中或从Session中移开。你可以通过使用HttpSessionBindingListener接口获得这些信息。当你的应用存储数据到Session中,或从Session中清除数据,Servlet都会通过HttpSessionBindingListener检杳什么类被绑定或被取消绑定。这个接口的方法会通报被绑定或被取消绑定的对象。 绪言 这是一份关于2.1版JavaServletAPI的说明文档,作为对这本文档的补充,你可以到http://java.sun.com/products/servlet/index.html下面下载Javadoc格式的文档。 谁需要读这份文档 这份文档描述了JavaServletAPI的最新版本2.1版。所以,这本书对于Servlet的开发者及servlet引擎的开发者同样适用。 JavaServletAPI的组成 JavaServletAPI由两个软件包组成:一个是对应HTTP的软件包,另一个是不对应HTTP的通用的软件包。这两个软件包的同时存在使得JavaServletAPI能够适应将来的其他请求-响应的协议。 这份文档以及刚才提及的Javadoc格式的文档都描述了这两个软件包,Javadoc格式的文档还描述了你应该如何使用这两个软件包中的所有方法。 有关规范 你也许对下面的这些Internet规范感兴趣,这些规范将直接影响到ServletAPI的发展和执行。你可以从http://info.internet.isi.edu/7c/in-notes/rfc/.cache找到下面提到的所有这些RFC规范。 RFC1738统一资源定位器(URL) RFC1808相关统一资源定位器 RFC1945超文本传输协议--HTTP/1.0 RFC2045多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第一部分:Internet信息体格式 RFC2046多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第二部分:媒体类型 RFC2047多用途网际邮件扩充协议(MIME)(多用途Internet邮件扩展)第三部分:信息标题扩展用于非ASCII文本 RFC2048多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第四部分:注册步骤 RFC2049多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第五部分:一致性标准和例子 RFC2068超文本传输协议--HTTP/1.1 RFC2069一个扩展HTTP:摘要访问鉴定 RFC2109HTTP状态管理机制 RFC2145HTTP版本号的使用和解释 RFC2324超文本CoffeePot控制协议(HTCPCP/1.0) 万维网协会(http://www.w3.org)管理着这些协议的规范和执行。 有关JavaServlets JavaTMservlets是一个不受平台约束的Java小程序,它可以被用来通过多种方法扩充一个Web服务器的功能。你可以把Servlet理解成Server上的applets,它被编译成字节码,这样它就可以被动态地载入并用效地扩展主机的处理能力。 Servlet与applets不同的地方是,它不运行在Web浏览器或其他图形化的用户界面上。Servlet通过servlet引擎运行在Web服务器中,以执行请求和响应,请求、响应的典型范例是HTTP协议。 一个客户端程序,可以是一个Web浏览器,或者是非其他的可以连接上Internet的程序,它会访问Web服务器并发出请求。这个请求被运行在Web服务器上的Servlet引擎处理,并返回响应到ServletServlet通过HTTP将这个响应转发到客户端。 在功能上,Servlet与CGI、NSAPI有点类似,但是,与他们不同的是:Servlet具有平台无关性。 JavaServlet概论 Servlet与其他普通的server扩展机制有以下进步: 因为它采用了不同的进程处理模式,所以它比CGI更快。 它使用了许多Web服务器都支持的标准的API。 它继承了Java的所有优势,包括易升级以及平台无关性。 它可以调用Java所提供的大量的API的功能模块。 这份文档说明了JavaServletAPI的类和接口的方法。有关更多的信息,请参看下面的API说明。 Servlet的生命周期 一个Javaservlet具有一个生命周期,这个生命周期定义了一个Servlet如何被载入并被初始化,如何接收请求并作出对请求的响应,如何被从服务中清除。Servlet的生命周期被javax.servlet.Servlet这个接口所定义。 所有的JavaServlet都会直接地或间接地执行javax.servlet.Servlet接口,这样它才能在一个Servlet引擎中运行。Servlet引擎是Web服务器按照JavaServletAPI定制的扩展。Servlet引擎提供网络服务,能够理解MIME请求,并提供一个运行Servlet的容器。 javax.servlet.Servlet接口定义了在Servlet的生命周期中特定时间以及特定顺序被调用的方法。 Servlet的解析和载入\r Servlet引擎解析并载入一个Servlet,这个过程可以发生在引擎启动时,需要一个Servlet去响应请求时,以及在此之间的任何时候。 Servlet引擎利用Java类载入工具载入一个ServletServlet引擎可以从一个本地的文件系统、一个远程的文件系统以及网络载入ServletServlet的初始化 Servlet引擎载入Servlet后,Servlet引擎必须对Servlet进行初始化,在这一过程中,你可以读取一些固定存储的数据、初始化JDBC的连接以及建立与其他资源的连接。 在初始化过程中,javax.servlet.Servlet接口的init()方法提供了Servlet的初始化信息。这样,Servlet可以对自己进行配置。 init()方法获得了一个Servlet配置对象(ServletConfig)。这个对象在Servlet引擎中执行,并允许Servlet通过它获处相关参数。这个对象使得Servlet能够访问ServletContext对象。 Servlet处理请求\r Servlet被初始化之后,它已经可以处理来自客户端的请求,每一个来自客户端的请求都被描述成一个ServletRequest对象,Servlet的响应被描述成一个ServletResponse对象。 当客户端发出请求时,Servlet引擎传递给Servlet一个ServletRequest对象和一个ServletResponse对象,这两个对象作为参数传递到service()方法中。 Servlet也可以执行ServletRequest接口和ServletResponse接口。ServletRequest接口使得Servlet有权使用客户端发出的请求。Servlet可以通过ServletInputStream对象读取请求信息。 ServletResponse接口允许Servlet建立响应头和状态代码。通过执行这个接口,Servlet有权使用ServletOutputStream类来向客户端返回数据。 多线程和映射\r 在多线程的环境下,Servlet必须能处理许多同时发生的请求。例外的情况是这个Servlet执行了SingleThreadModel接口,如果是那样的话,Servlet只能同时处理一个请求。 Servlet依照Servlet引擎的映射来响应客户端的请求。一个映射对包括一个Servlet实例以及一个Servlet返回数据的URL,例如:HelloServletwith/hello/index.html。 然而,一个映射可能是由一个URL和许多Servlet实例组成,例如:一个分布式的Servlet引擎可能运行在不止一个的服务器中,这样的话,每一个服务器中都可能有一个Servlet实例,以平衡进程的载入。作为一个Servlet的开发者,你不能假定一个Servlet只有一个实例。 Servlet的卸载 Servlet引擎并不必需保证一个Servlet在任何时候或在服务开启的任何时候都被载入。Servlet引擎可以自由的在任何时候使用或清除一个Servlet。因此,我们不能依赖一个类或实例来存储重要的信息。 当Servlet引擎决定卸载一个Servlet时(例如,如果这个引擎被关闭或者需要让资源),这个引擎必须允许Servlet释放正在使用的资源并存储有关资料。为了完成以上工作,引擎会调用Servlet的destroy()方法。 在卸载一个Servlet之前,Servlet引擎必须等待所有的service()方法完成或超时结束(Servlet引擎会对超时作出定义)。当一个Servlet被卸载时,引擎将不能给Servlet发送任何请求。引擎必须释放Servlet并完成无用存储单元的收集 Servlet映射技术\r 作为一个Servlet引擎的开发者,你必须对于如何映射客户端的请求到Servlet有大量的适应性。这份说明文档不规定映射如何发生。但是,你必须能够自由地运用下面的所有技术: 映射一个Servlet到一个URL 例如,你可以指定一个特殊的Servlet它仅被来自/feedback/index.html的请求调用。 映射一个Servlet到以一个指定的目录名开始的所有URL 例如,你可以映射一个Servlet到/catalog,这样来自/catalog/、/catalog/garden和/catalog/housewares/index.html的请求都会被映射到这个Servlet。但是来自/catalogtwo或/catalog.html的请求没被映射。 映射一个Servlet到所有以一个特定的字段结尾的所有URL 例如,你可以映射一个来自于所有以in.thtml结尾的请求到一个特定的Servlet。 映射一个Servlet到一个特殊的URL/servlet/servlet_name。 例如,如果你建立了一个名叫listattributes的Servlet,你可以通过使用/servlet/listattributes来访问这个Servlet。 通过类名调用Servlet 例如,如果Servlet引擎接收了来自/servlet/com.foo.servlet.MailServlet的请求,Servlet引擎会载入这个com.foo.servlet.MailServlet类,建立实例,并通过这个Servlet来处理请求。 Servlet环境 ServletContext接口定义了一个Servlet环境对象,这个对象定义了一个在Servlet引擎上的Servlet的视图。通过使用这个对象,Servlet可以记录事件、得到资源并得到来自Servlet引擎的类(例如RequestDispatcher对象)。一个Servlet只能运行在一个Servlet环境中,但是不同的Servlet可以在Servlet引擎上有不同的视图。 如果Servlet引擎支持虚拟主机,每个虚拟主机有一个Servlet环境。一个Servlet环境不能在虚拟主机之间共享。 Servlet引擎能够允许一个Servlet环境有它自己的活动范围。 例如,一个Servlet环境是属于bank应用的,它将被映射到/bank目录下。在这种情况下,一个对getContext方法的调用会返回/bank的Servlet环境。 HTTP会话 HTTP是一个没有状态的协议。要建立一个有效的Web服务应用,你必须能够识别一个连续的来自远端的客户机的唯一的请求。随着时间的过去,发展了许多会话跟踪的技术,但是使用起来都比较麻烦。 JavaServletAPI提供了一个简单的接口,通过这个接口,Servlet引擎可以有效地跟踪用户的会话。 建立Session 因为HTTP是一个请求-响应协议,一个会话在客户机加入之前会被认为是一个新的会话。加入的意思是返回会话跟踪信息到服务器中,指出会话已被建立。在客户端加入之前,我们不能判断下一个客户端请求是目前会话的一部分。 在下面的情况下,Session会被认为是新的Session。 客户端的Session在此之前还不知道 客户端选择不加入Session,例如,如果客户端拒绝接收来自服务器的cookie 作为一个Servlet的开发者,你必须决定你的Web应用是否处理客户机不加入或不能加入Session。服务器会在Web服务器或Servlet规定的时间内维持一个Session对象。当Session终止时,服务器会释放Session对象以及所有绑定在Session上的对象。 绑定对象到Session中 如果有助于你处理应用的数据需求,你也许需要绑定对象到Session中,你可以通过一个唯一的名字绑定任何的对象到Session中,这时,你需要使用HttpSession对象。任何绑定到Session上的对象都可以被处理同一会话的Servlet调用。 有些对象可能需要你知道什么时候会被放置到Session中或从Session中移开。你可以通过使用HttpSessionBindingListener接口获得这些信息。当你的应用存储数据到Session中,或从Session中清除数据,Servlet都会通过HttpSessionBindingListener检杳什么类被绑定或被取消绑定。这个接口的方法会通报被绑定或被取消绑定的对象。 软件包:javax.servlet.http 所包含的接口:HttpServletRequest;HttpServletResponse;HttpSession;HttpSessionBindingListener;HttpSessionContext。 所包含的类:Cookie;HttpServlet;HttpSessionBindingEvent;HttpUtils。 一、HttpServletRequest接口 定义\ publicinterfaceHttpServletRequestextendsServletRequest; 用来处理一个对Servlet的HTTP格式的请求信息。 方法 1、getAuthType publicStringgetAuthType(); 返回这个请求的身份验证模式。 2、getCookies publicCookie[]getCookies(); 返回一个数组,该数组包含这个请求中当前的所有cookie。如果这个请求中没有cookie,返回一个空数组。 3、getDateHeader publiclonggetDateHeader(Stringname); 返回指定的请求头域的值,这个值被转换成一个反映自1970-1-1日(GMT)以来的精确到毫秒的长整数。 如果头域不能转换,抛出一个IllegalArgumentException。如果这个请求头域不存在,这个方法返回-1。 4、getHeader publicStringgetHeader(Stringname); 返回一个请求头域的值。(译者注:与上一个方法不同的是,该方法返回一个字符串) 如果这个请求头域不存在,这个方法返回-1。 5、getHeaderNames publicEnumerationgetHeaderNames(); 该方法返回一个String对象的列表,该列表反映请求的所有头域名。 有的引擎可能不允许通过这种方法访问头域,在这种情况下,这个方法返回一个空的列表。 6、getIntHeader publicintgetIntHeader(Stringname); 返回指定的请求头域的值,这个值被转换成一个整数。 如果头域不能转换,抛出一个IllegalArgumentException。如果这个请求头域不存在,这个方法返回-1。 7、getMethod publicStringgetMethod(); 返回这个请求使用的HTTP方法(例如:GET、POST、PUT) 8、getPathInfo publicStringgetPathInfo(); 这个方法返回在这个请求的URL的Servlet路径之后的请求URL的额外的路径信息。如果这个请求URL包括一个查询字符串,在返回值内将不包括这个查询字符串。这个路径在返回之前必须经过URL解码。如果在这个请求的URL的Servlet路径之后没有路径信息。这个方法返回空值。 9、getPathTranslated publicStringgetPathTranslated(); 这个方法获得这个请求的URL的Servlet路径之后的额外的路径信息,并将它转换成一个真实的路径。在进行转换前,这个请求的URL必须经过URL解码。如果在这个URL的Servlet路径之后没有附加路径信息。这个方法返回空值。 10、getQueryString publicStringgetQueryString(); 返回这个请求URL所包含的查询字符串。一个查询字串符在一个URL中由一个“?”引出。如果没有查询字符串,这个方法返回空值。 11、getRemoteUser publicStringgetRemoteUser 返回作了请求的用户名,这个信息用来作HTTP用户论证。 如果在请求中没有用户名信息,这个方法返回空值。 12、getRequestedSessionId publicStringgetRequestedSessionId(); 返回这个请求相应的sessionid。如果由于某种原因客户端提供的sessionid是无效的,这个sessionid将与在当前session中的sessionid不同,与此同时,将建立一个新的session。 如果这个请求没与一个session关联,这个方法返回空值。 13、getRequestURI publicStringgetRequestURI(); 从HTTP请求的第一行返回请求的URL中定义被请求的资源的部分。如果有一个查询字符串存在,这个查询字符串将不包括在返回值当中。例如,一个请求通过/catalog/books?id=1这样的URL路径访问,这个方法将返回/catalog/books。这个方法的返回值包括了Servlet路径和路径信息。 如果这个URL路径中的的一部分经过了URL编码,这个方法的返回值在返回之前必须经过解码。 14、getServletPath publicStringgetServletPath(); 这个方法返回请求URL反映调用Servlet的部分。例如,一个Servlet被映射到/catalog/summer这个URL路径,而一个请求使用了/catalog/summer/casual这样的路径。所谓的反映调用Servlet的部分就是指/catalog/summer。 如果这个Servlet不是通过路径匹配来调用。这个方法将返回一个空值。 15、getSession publicHttpSessiongetSession(); publicHttpSessiongetSession(booleancreate); 返回与这个请求关联的当前的有效的session。如果调用这个方法时没带参数,那么在没有session与这个请求关联的情况下,将会新建一个session。如果调用这个方法时带入了一个布尔型的参数,只有当这个参数为真时,session才会被建立。 为了确保session能够被完全维持。Servlet开发者必须在响应被提交之前调用该方法。 如果带入的参数为假,而且没有session与这个请求关联。这个方法会返回空值。 16、isRequestedSessionIdValid publicbooleanisRequestedSessionIdValid(); 这个方法检查与此请求关联的session当前是不是有效。如果当前请求中使用的session无效,它将不能通过getSession方法返回。 17、isRequestedSessionIdFromCookie publicbooleanisRequestedSessionIdFromCookie(); 如果这个请求的sessionid是通过客户端的一个cookie提供的,该方法返回真,否则返回假。 18、isRequestedSessionIdFromURL publicbooleanisRequestedSessionIdFromURL(); 如果这个请求的sessionid是通过客户端的URL的一部分提供的,该方法返回真,否则返回假。请注意此方法与isRequestedSessionIdFromUrl在URL的拼写上不同。 以下方法将被取消\\r 19、isRequestedSessionIdFromUrl publicbooleanisRequestedSessionIdFromUrl(); 该方法被isRequestedSessionIdFromURL代替。 二、HttpServletResponse接口 定义\\r publicinterfaceHttpServletResponseextendsServletResponse 描述一个返回到客户端的HTTP回应。这个接口允许Servlet程序员利用HTTP协议规定的头信息。 成员变量 publicstaticfinalintSC_CONTINUE=100; publicstaticfinalintSC_SWITCHING_PROTOCOLS=101; publicstaticfinalintSC_OK=200; publicstaticfinalintSC_CREATED=201; publicstaticfinalintSC_ACCEPTED=202; publicstaticfinalintSC_NON_AUTHORITATIVE_INFORMATION=203; publicstaticfinalintSC_NO_CONTENT=204; publicstaticfinalintSC_RESET_CONTENT=205; publicstaticfinalintSC_PARTIAL_CONTENT=206; publicstaticfinalintSC_MULTIPLE_CHOICES=300; publicstaticfinalintSC_MOVED_PERMANENTLY=301; publicstaticfinalintSC_MOVED_TEMPORARILY=302; publicstaticfinalintSC_SEE_OTHER=303; publicstaticfinalintSC_NOT_MODIFIED=304; publicstaticfinalintSC_USE_PROXY=305; publicstaticfinalintSC_BAD_REQUEST=400; publicstaticfinalintSC_UNAUTHORIZED=401; publicstaticfinalintSC_PAYMENT_REQUIRED=402; publicstaticfinalintSC_FORBIDDEN=403; publicstaticfinalintSC_NOT_FOUND=404; publicstaticfinalintSC_METHOD_NOT_ALLOWED=405; publicstaticfinalintSC_NOT_ACCEPTABLE=406; publicstaticfinalintSC_PROXY_AUTHENTICATION_REQUIRED=407; publicstaticfinalintSC_REQUEST_TIMEOUT=408; publicstaticfinalintSC_CONFLICT=409; publicstaticfinalintSC_GONE=410; publicstaticfinalintSC_LENGTH_REQUIRED=411; publicstaticfinalintSC_PRECONDITION_FAILED=412; publicstaticfinalintSC_REQUEST_ENTITY_TOO_LARGE=413; publicstaticfinalintSC_REQUEST_URI_TOO_LONG=414; publicstaticfinalintSC_UNSUPPORTED_MEDIA_TYPE=415; publicstaticfinalintSC_INTERNAL_SERVER_ERROR=500; publicstaticfinalintSC_NOT_IMPLEMENTED=501; publicstaticfinalintSC_BAD_GATEWAY=502; publicstaticfinalintSC_SERVICE_UNAVAILABLE=503; publicstaticfinalintSC_GATEWAY_TIMEOUT=504; publicstaticfinalintSC_HTTP_VERSION_NOT_SUPPORTED=505; 以上HTTP产状态码是由HTTP/1.1定义的。 方法 1、addCookie publicvoidaddCookie(Cookiecookie); 在响应中增加一个指定的cookie。可多次调用该方法以定义多个cookie。为了设置适当的头域,该方法应该在响应被提交之前调用。 2、containsHeader publicbooleancontainsHeader(Stringname); 检查是否设置了指定的响应头。 3、encodeRedirectURL publicStringencodeRedirectURL(Stringurl); 对sendRedirect方法使用的指定URL进行编码。如果不需要编码,就直接返回这个URL。之所以提供这个附加的编码方法,是因为在redirect的情况下,决定是否对URL进行编码的规则和一般情况有所不同。所给的URL必须是一个绝对URL。相对URL不能被接收,会抛出一个IllegalArgumentException。 所有提供给sendRedirect方法的URL都应通过这个方法运行,这样才能确保会话跟踪能够在所有浏览器中正常运行。 4、encodeURL publicStringencodeURL(Stringurl); 对包含sessionID的URL进行编码。如果不需要编码,就直接返回这个URL。Servlet引擎必须提供URL编码方法,因为在有些情况下,我们将不得不重写URL,例如,在响应对应的请求中包含一个有效的session,但是这个session不能被非URL的(例如cookie)的手段来维持。 所有提供给Servlet的URL都应通过这个方法运行,这样才能确保会话跟踪能够在所有浏览器中正常运行。 5、sendError publicvoidsendError(intstatusCode)throwsIOException; publicvoidsendError(intstatusCode,Stringmessage)throws IOException; 用给定的状态码发给客户端一个错误响应。如果提供了一个message参数,这将作为响应体的一部分被发出,否则,服务器会返回错误代码所对应的标准信息。 调用这个方法后,响应立即被提交。在调用这个方法后,Servlet不会再有更多的输出。 6、sendRedirect publicvoidsendRedirect(Stringlocation)throwsIOException; 使用给定的路径,给客户端发出一个临时转向的响应(SC_MOVED_TEMPORARILY)。给定的路径必须是绝对URL。相对URL将不能被接收,会抛出一个IllegalArgumentException。 这个方法必须在响应被提交之前调用。调用这个方法后,响应立即被提交。在调用这个方法后,Servlet不会再有更多的输出。 7、setDateHeader publicvoidsetDateHeader(Stringname,longdate); 用一个给定的名称和日期值设置响应头,这里的日期值应该是反映自1970-1-1日(GMT)以来的精确到毫秒的长整数。如果响应头已经被设置,新的值将覆盖当前的值。 8、setHeader publicvoidsetHeader(Stringname,Stringvalue); 用一个给定的名称和域设置响应头。如果响应头已经被设置,新的值将覆盖当前的值。 9、setIntHeader publicvoidsetIntHeader(Stringname,intvalue); 用一个给定的名称和整形值设置响应头。如果响应头已经被设置,新的值将覆盖当前的值。 10、setStatus publicvoidsetStatus(intstatusCode); 这个方法设置了响应的状态码,如果状态码已经被设置,新的值将覆盖当前的值。 以下的几个方法将被取消\ 11、encodeRedirectUrl publicStringencodeRedirectUrl(Stringurl); 该方法被encodeRedirectURL取代。 12、encodeUrl publicStringencodeUrl(Stringurl); 该方法被encodeURL取代。 13、setStatus publicvoidsetStatus(intstatusCode,Stringmessage); 这个方法设置了响应的状态码,如果状态码已经被设置,新的值将覆盖当前的值。如果提供了一个message,它也将会被作为响应体的一部分被发送。 三、HttpSession接口 定义\ publicinterfaceHttpSession 这个接口被Servlet引擎用来实现在HTTP客户端和HTTP会话两者的关联。这种关联可能在多外连接和请求中持续一段给定的时间。session用来在无状态的HTTP协议下越过多个请求页面来维持状态和识别用户。 一个session可以通过cookie或重写URL来维持。 方法 1、getCreationTime publiclonggetCreationTime(); 返回建立session的时间,这个时间表示为自1970-1-1日(GMT)以来的毫秒数。 2、getId publicStringgetId(); 返回分配给这个session的标识符。一个HTTPsession的标识符是一个由服务器来建立和维持的唯一的字符串。 3、getLastAccessedTime publiclonggetLastAccessedTime(); 返回客户端最后一次发出与这个session有关的请求的时间,如果这个session是新建立的,返回-1。这个时间表示为自1970-1-1日(GMT)以来的毫秒数。 4、getMaxInactiveInterval publicintgetMaxInactiveInterval(); 返加一个秒数,这个秒数表示客户端在不发出请求时,session被Servlet引擎维持的最长时间。在这个时间之后,Servlet引擎可能被Servlet引擎终止。如果这个session不会被终止,这个方法返回-1。 当session无效后再调用这个方法会抛出一个IllegalStateException。 5、getValue publicObjectgetValue(Stringname); 返回一个以给定的名字绑定到session上的对象。如果不存在这样的绑定,返回空值。 当session无效后再调用这个方法会抛出一个IllegalStateException。 6、getValueNames publicString[]getValueNames(); 以一个数组返回绑定到session上的所有数据的名称。 当session无效后再调用这个方法会抛出一个IllegalStateException。 7、invalidate publicvoidinvalidate(); 这个方法会终止这个session。所有绑定在这个session上的数据都会被清除。并通过HttpSessionBindingListener接口的valueUnbound方法发出通告。 8、isNew publicbooleanisNew(); 返回一个布尔值以判断这个session是不是新的。如果一个session已经被服务器建立但是还没有收到相应的客户端的请求,这个session将被认为是新的。这意味着,这个客户端还没有加入会话或没有被会话公认。在他发出下一个请求时还不能返回适当的session认证信息。 当session无效后再调用这个方法会抛出一个IllegalStateException。 9、putValue publicvoidputValue(Stringname,Objectvalue); 以给定的名字,绑定给定的对象到session中。已存在的同名的绑定会被重置。这时会调用HttpSessionBindingListener接口的valueBound方法。 当session无效后再调用这个方法会抛出一个IllegalStateException。 10、removeValue publicvoidremoveValue(Stringname); 取消给定名字的对象在session上的绑定。如果未找到给定名字的绑定的对象,这个方法什么出不做。这时会调用HttpSessionBindingListener接口的valueUnbound方法。 当session无效后再调用这个方法会抛出一个IllegalStateException。 11、setMaxInactiveInterval publicintsetMaxInactiveInterval(intinterval); 设置一个秒数,这个秒数表示客户端在不发出请求时,session被Servlet引擎维持的最长时间。 以下这个方法将被取消\ 12、getSessionContext publicHttpSessionContextgetSessionContext(); 返回session在其中得以保持的环境变量。这个方法和其他所有HttpSessionContext的方法一样被取消了。 四、HttpSessionBindingListener接口 定义\ publicinterfaceHttpSessionBindingListener 这个对象被加入到HTTP的session中,执行这个接口会通告有没有什么对象被绑定到这个HTTPsession中或被从这个HTTPsession中取消绑定。 方法 1、valueBound publicvoidvalueBound(HttpSessionBindingEventevent); 当一个对象被绑定到session中,调用此方法。HttpSession.putValue方法被调用时,Servlet引擎应该调用此方法。 2、valueUnbound publicvoidvalueUnbound(HttpSessionBindingEventevent); 当一个对象被从session中取消绑定,调用此方法。HttpSession.removeValue方法被调用时,Servlet引擎应该调用此方法。 五、HttpSessionContext接口 定义\ 此接口将被取消\ publicinterfaceHttpSessionContext 这个对象是与一组HTTPsession关联的单一的实体。 这个接口由于安全的原因被取消,它出现在目前的版本中仅仅是为了兼容性的原因。这个接口的方法将模拟以前的版本的定义返回相应的值。 方法 1、getSession publicHttpSessiongetSession(StringsessionId); 当初用来返回与这个sessionid相关的session。现在返回空值。 2、getIds publicEnumerationgetIds(); 当初用来返回这个环境下所有sessionid的列表。现在返回空的列表。 六、Cookie类\ 定义\ publicclassCookieimplementsCloneable 这个类描述了一个cookie,有关cookie的定义你可以参照NetscapeCommunicationsCorporation的说明,也可以参照RFC2109。 构造函数 publicCookie(Stringname,Stringvalue); 用一个name-value对定义一个cookie。这个name必须能被HTTP/1.1所接受。 以字符$开头的name被RFC2109保留。 给定的name如果不能被HTTP/1.1所接受,该方法抛出一个IllegalArgumentException。 方法 1、getComment publicStringgetComment(); 返回描述这个cookie目的的说明,如果未定义这个说明,返回空值。 2、getDomain publicStringgetDomain(); 返回这个cookie可以出现的区域,如果未定义区域,返回空值。 3、getMaxAge publicintgetMaxAge(); 这个方法返回这个cookie指定的最长存活时期。如果未定义这个最长存活时期,该方法返回-1。 4、getName publicStringgetName(); 该方法返回cookie名。 5、getPath publicStringgetPath(); 返回这个cookie有效的所有URL路径的前缀,如果未定义,返回空值。 6、getSecure publicbooleangetSecure(); 如果这个cookie只通过安全通道传输返回真,否则返回假。 7、getValue publicStringgetValue(); 该方法返回cookie的值。 8、getVersion publicintgetVersion(); 返回cookie的版本。版本1由RFC2109解释。版本0由NetscapeCommunicationsCorporation的说明解释。新构造的cookie默认使用版本0。 9、setComment publicvoidsetComment(Stringpurpose); 如果一个用户将这个cookie提交给另一个用户,必须通过这个说明描述这个cookie的目的。版本0不支持这个属性。 10、setDomain publicvoidsetDomain(Stringpattern); 这个方法设置cookie的有效域的属性。这个属性指定了cookie可以出现的区域。一个有效域以一个点开头(.foo.com),这意味着在指定的域名解析系统的区域中(可能是www.foo.com但不是a.b.foo.com)的主机可以看到这个cookie。默认情况是,cookie只能返回保存它的主机。 11、setMaxAge publicvoidsetMaxAge(intexpiry); 这个方法设定这个cookie的最长存活时期。在该存活时期之后,cookie会被终目。负数表示这个cookie不会生效,0将从客户端删除这个cookie。 12、setPath publicvoidsetPath(Stringuri); 这个方法设置cookie的路径属性。客户端只能向以这个给定的路径String开头的路径返回cookie。 13、setSecure publicvoidsetSecure(booleanflag); 指出这个cookie只能通过安全通道(例如HTTPS)发送。只有当产生这个cookie的服务器使用安全协议发送这个cookie值时才能这样设置。 14、setValue publicvoidsetValue(StringnewValue); 设置这个cookie的值,对于二进制数据采用BASE64编码。 版本0不能使用空格、{}、()、=、,、“”、/、?、@、:以及;。 15、setVersion publicvoidsetVersion(intv); 设置cookie的版本号 七、HttpServlet类\ 定义\ publicclassHttpServletextendsGenericServletimplements Serializable 这是一个抽象类,用来简化HTTPServlet写作的过程。它是GenericServlet类的扩充,提供了一个处理HTTP协议的框架。 在这个类中的service方法支持例如GET、POST这样的标准的HTTP方法。这一支持过程是通过分配他们到适当的方法(例如doGet、doPost)来实现的。 方法 1、doDelete protectedvoiddoDelete(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException, IOException; 被这个类的service方法调用,用来处理一个HTTPDELETE操作。这个操作允许客户端请求从服务器上删除URL。这一操作可能有负面影响,对此用户就负起责任。 这一方法的默认执行结果是返回一个HTTPBAD_REQUEST错误。当你要处理DELETE请求时,你必须重载这一方法。 2、doGet protectedvoiddoGet(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException, IOException; 被这个类的service方法调用,用来处理一个HTTPGET操作。这个操作允许客户端简单地从一个HTTP服务器“获得”资源。对这个方法的重载将自动地支持HEAD方法。 GET操作应该是安全而且没有负面影响的。这个操作也应该可以安全地重复。 这一方法的默认执行结果是返回一个HTTPBAD_REQUEST错误。 3、doHead protectedvoiddoHead(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException, IOException; 被这个类的service方法调用,用来处理一个HTTPHEAD操作。默认的情况是,这个操作会按照一个无条件的GET方法来执行,该操作不向客户端返回任何数据,而仅仅是返回包含内容长度的头信息。 与GET操作一样,这个操作应该是安全而且没有负面影响的。这个操作也应该可以安全地重复。 这个方法的默认执行结果是自动处理HTTPHEAD操作,这个方法不需要被一个子类执行。 4、doOptions protectedvoiddoOptions(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException, IOException; 被这个类的service方法调用,用来处理一个HTTPOPTION操作。这个操作自动地决定支持哪一种HTTP方法。例如,一个Servlet写了一个HttpServlet的子类并重载了doGet方法,doOption会返回下面的头: Allow:GET,HEAD,TRACE,OPTIONS 你一般不需要重载这个方法。 5、doPost protectedvoiddoPost(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException, IOException; 被这个类的service方法调用,用来处理一个HTTPPOST操作。这个操作包含请求体的数据,Servlet应该按照他行事。 这个操作可能有负面影响。例如更新存储的数据或在线购物。 这一方法的默认执行结果是返回一个HTTPBAD_REQUEST错误。当你要处理POST操作时,你必须在HttpServlet的子类中重载这一方法。 6、doPut protectedvoiddoPut(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException, IOException; 被这个类的service方法调用,用来处理一个HTTPPUT操作。这个操作类似于通过FTP发送文件。 这个操作可能有负面影响。例如更新存储的数据或在线购物。 这一方法的默认执行结果是返回一个HTTPBAD_REQUEST错误。当你要处理PUT操作时,你必须在HttpServlet的子类中重载这一方法。 7、doTrace protectedvoiddoTrace(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException, IOException; 被这个类的service方法调用,用来处理一个HTTPTRACE操作。这个操作的默认执行结果是产生一个响应,这个响应包含一个反映trace请求中发送的所有头域的信息。 当你开发Servlet时,在多数情况下你需要重载这个方法。 8、getLastModified protectedlonggetLastModified(HttpServletRequestrequest); 返回这个请求实体的最后修改时间。为了支持GET操作,你必须重载这一方法,以精确地反映最后修改的时间。这将有助于浏览器和代理服务器减少装载服务器和网络资源,从而更加有效地工作。返回的数值是自1970-1-1日(GMT)以来的毫秒数。 默认的执行结果是返回一个负数,这标志着最后修改时间未知,它也不能被一个有条件的GET操作使用。 9、service protectedvoidservice(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException, IOException; publicvoidservice(ServletRequestrequest,ServletResponseresponse) throwsServletException,IOException; 这是一个Servlet的HTTP-specific方案,它分配请求到这个类的支持这个请求的其他方法。 当你开发Servlet时,在多数情况下你不必重载这个方法。 八、HttpSessionBindingEvent类\ 定义\ publicclassHttpSessionBindingEventextendsEventObject 这个事件是在监听到HttpSession发生绑定和取消绑定的情况时连通HttpSessionBindingListener的。这可能是一个session被终止或被认定无效的结果。 事件源是HttpSession.putValue或HttpSession.removeValue。 构造函数 publicHttpSessionBindingEvent(HttpSessionsession,Stringname); 通过引起这个事件的Session和发生绑定或取消绑定的对象名构造一个新的HttpSessionBindingEvent。 方法 1、getName publicStringgetName(); 返回发生绑定和取消绑定的对象的名字。 2、getSession publicHttpSessiongetSession(); 返回发生绑定和取消绑定的session的名字。 九、HttpUtils类\ 定义\ publicclassHttpUtils 收集HTTPServlet使用的静态的有效的方法。 方法 1、getRequestURL publicstaticStringBuffergetRequestURL(HttpServletRequest request); 在服务器上重建客户端用来建立请求的URL。这个方法反映了不同的协议(例如http和https)和端口,但不包含查询字符串。 这个方法返回一个StringBuffer而不是一个String,这样URL可以被Servlet开发者有效地修改。 2、parsePostData publicstaticHashtableparsePostData(intlen, ServletInputstreamin); 解析一个包含MIME类型application/x-www-form-urlencoded的数据的流,并创建一个具有关键值-数据对的hashtable。这里的关键值是字符串,数据是该字符串所对应的值的列表。一个关键值可以在POST的数据中出现一次或多次。这个关键值每出现一次,它的相应的值就被加入到hashtable中的字符串所对应的值的列表中。 从POST数据读出的数据将经过URL解码,+将被转换为空格以十六进制传送的数据(例如%xx)将被转换成字符。 当POST数据无效时,该方法抛出一个IllegalArgumentException。 3、parseQueryString publicstaticHashtableparseQueryString(Strings); 解析一个查询字符串,并创建一个具有关键值-数据对的hashtable。这里的数据是该字符串所对应的值的列表。一个关键值可以出现一次或多次。这个关键值每出现一次,它的相应的值就被加入到hashtable中的字符串所对应的值的列表中。 从查询字符串读出的数据将经过URL解码,+将被转换为空格以十六进制传送的数据(例如%xx)将被转换成字符。 当查询字符串无效时,该方法抛出一个IllegalArgumentException。 bytecode 字节码:由Java编译器和Java解释程序生成的机器代码。 cookie 由Web服务器建立的数据,该数据存储在用户的计算机上,提供了一个Web站点跟踪用户的参数并存储在用户自己硬盘上的方法。 HTTP 超文本传输协议。一个请求响应协议用来连接WWW服务器向客户端浏览器传输HTML页面。 输入流对象\r 一个对象,由ServletInputStream类定义,被Servlet用来从客户端读取请求。 映射\r 由Servlet实例和Servlet返回数据的URL组成的一对,例如,HelloServlet和/hello/index.html。 输出流对象\r 一个对象,由ServletOutputStreamclass类定义,被Servlet用来向客户端返回数据。 requestdispatcherobject 由RequestDispatcher接口定义的一个对象,用来从客户端接收请求,并将其发送到Web服务器上可用的其他资源(例如Servlet、CGI、HTML文件或JSP文件)。 sandboxedservlet 在一个安全性约束下运行的Servletservlet 一个小的,具有平台无关性的,没有图形用户界面的Java程序。它可以在许多方面扩充Web服务的功能。 servletconfigurationobject ServletConfig接口定义的一个对象,用来配置一个Servletservletcontextobject ServletContext接口定义的一个对象。给予Servlet有关Servlet引擎的信息。 servlet引擎\r 由Web服务器提供商制作的一个环境,可以允许Servlet在具体的Web服务器上运行。 servlet请求对象 由ServletRequest接口定义的一个对象,允许Servlet获得用关客户端请求的数据。 servletresponseobject 由ServletResponse接口定义的一个对象,允许Servlet作出响应。 servletrunner JavaServletDeveloper’sKit(JSDK)中的sun.servlet.http.HttpServer过程,它使得Servlet得以运行。 会话跟踪 在一个Web应用程序中,识别一个从同一个客户端发出的连续的唯一的请求的能力。 SSL 加密套接字协议层。一个安全协议,用来在Iternet上的客户端浏览器和服务器交换密钥和加密数据。 URI 统一资源标识。定义一个Internet地址,它是一个URL的超集。 URL 统一资源路径。这个地址定义了到达一个WWW上的文件的路线,通常由协议前缀、域名、目录名和文件名组成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值