[ Team LiB ] |
Servlet APIThe Servlet API is a comprehensive set of functions which provides all the functions required for complex interactions between a Web client and a Web container, including session management, security, dispatching requests, and more. Package StructureAll the servlet classes and interfaces are organized into the following packages:
In the following sections, we'll look at the important interfaces and classes that make up the servlet implementation, along with examples for each of the operations. The Servlet InterfaceThe Servlet interface is the base interface for developing all servlets. The GenericServlet interface, described later, implements this interface. The interface defines the basic methods that a servlet running inside a servlet engine defines to process client requests. As explained earlier, the Servlet interface defines the following life cycle methods: The interface also defines the getServletConfig() method, which returns the ServletConfig object that holds the initialization parameters and other configuration of the servlet defined by the user. These parameters are usually defined in the deployment descriptor of the Web application. Developers who want to implement the Servlet interface should take care of storing the ServletConfig object passed to the init method if the getServletConfig() method has to return the object when the servlet needs the configuration object. This interface also provides a getServletInfo() method, which can return information about the servlet, such as its author, version, and copyright text. ServletConfig InterfaceThis configuration object, which is passed into the servlet when it's instantiated (through the init method), provides user configuration information as name-value pairs. Table 14.3 lists the methods this object defines.
The following snippet reads a list of initialization parameters. In this case, it reads logging-related parameters, such as the debug and threshold limit, and prints their values on the console. You can use the read values to turn on logging and the threshold level in a real-world scenario. public void init(ServletConfig config) throws ServletException { super.init(config); Enumeration params = getInitParameterNames(); System.out.println("The init parameters are: "); while (params.hasMoreElements()) { String tempParam=(String)params.nextElement(); String paramValue=(String)getInitParameter(tempParam); System.out.println(tempParam+"="+paramValue); }} } The configuration interface also provides the getServletName() function to return the name of the servlet instance. The servlet names are usually provided in the Web application deployment descriptor (web.xml). The following XML snippet provides an example of the initialization parameters and servlet name that are used by the functions we covered here: <servlet> <servlet-name>SimpleServlet2</servlet-name> <servlet-class>wlsunleashed.servlets.SimpleServlet2</servlet-class> <init-param> <param-name>threshold</param-name> <param-value>1</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>false</param-value> </init-param> </servlet> ServletContext InterfaceThe ServletContext interface is the servlet's view of the Web container. As mentioned earlier, the getServletContext() method of ServletConfig returns the ServletContext object. This interface provides a lot of methods, and for easier understanding we can classify the methods into the categories in the following sections. Servlet Environment PropertiesThis interface provides the same methods defined in Table 14.3. Table 14.4 summarizes a list of additional methods defined in the ServletContext interface for obtaining the servlet and servlet's runtime environment properties along with the sample output for each of the methods Servlet Forwarding and IncludingOne of the major functions of the servlet context object is to give access to RequestDispatcher objects. The RequestDispatacher objects are used to forward and/or include other resources in a servlet response. The dispatchers can be obtained by one of the following methods:
RequestDispatchers are discussed in detail later in the chapter. Resources and ContextsThe ServletContext object is also used to get the servlet context of a given URL that might correspond to another Web application in the Web container. The ServletContext interface provides the following functions for getting the list of resources in a Web application. The resources returned are with respect to the specified paths.
Additionally, this object provides the getResourceAsStream() method for obtaining the requested resource as an input stream object. Given the path, this method gives the servlet the power to access any resource at any location. These methods give the servlet container the capability to make a resource available to any servlet, irrespective of its location. Additionally, they don't use class loaders to perform this function because it's done with equivalent functions defined in the java.lang.Class definition. Logging RoutinesIf a message has to be logged in the case of an exception, ServletContext provides a routine two flavors of log() functions. The first version takes a specified user message, and the second version takes a user message and a Throwable object as arguments. The detailed message and the exception are logged to the application log file. These log routines by no means represent a complete logging framework. Better logging capabilities have been introduced in JDK 1.4. You can refer to the related documentation at http://java.sun.com/j2se/1.4.1/docs/api/java/util/logging/package-summary.html. Interservlet Communication RoutinesApplication objects can be handled as the ServletContext object using the getters and setters defined in the interface. ServletContext defines the getters (getAttribute() and getAttributeNames()) to get the value of a previously set attribute (using the setAttribute() method) or an enumeration containing the names supported in the context. The attributes set in the context can be removed using the removeAttribute() method. Attributes can be used to exchange application objects between different parts of the Web application. For example, LoginServlet can set the name of the user logging into a system and this value can be also used in all other servlets during logging, authentication, and so forth. The init() method of LoginServlet can be changed to include the attribute manipulation explained earlier: public void init(ServletConfig config) throws ServletException { super.init(config); //Other EJB Look code ServletContext ctx = config.getServletContext(); ctx.setAttribute("com.username", config.getInitParameter("def_username")); } The attribute com.username defined in the code snippet can be accessed by any other servlet in the same Web application for purposes such as logging. public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); // Other logic //PrintWriter pw = resp.getWriter(); // value of username from the servletcontext set earlier userlog("USER :"+ getServletContext() .getAttribute("com.username").toString()); // Other logic } As you can see, using the context attribute is similar to using a global variable. But this isn't a recommended practice when you need global variables. Context should not be used as a data store when it might be used by a single component. The data should be kept as close as possible to the components using it. The context should be used only if a majority of the components need specific data. TIP Context could be used for caching lookup values. ServletRequest InterfaceThis interface encapsulates all the information associated with a client request including request parameters (form field values and URL parameters), information such as session identifier, and client properties such as address, hostname, and so on. The service() method of the Servlet interface, which processes all the client requests, takes the ServletRequest as its argument. The Web container creates this object. We look at each of the important methods and their use when we discuss HttpServletRequest—one of the best-known subinterfaces for implementing HTTP. The servlet request object gives access to the input stream to read binary data from clients, and also provides methods such as getParameter() to access character data in the input. ServletResponse InterfaceThe servlet container uses this interface to send replies back to the client. This object is also passed as an argument to the service method. This object is created by the Web container and is initially empty. HttpServletResponse is the subinterface of ServletResponse that's used in HttpServlets. We'll look at the methods, along with HttpServletResponse, in detail later in the chapter. The response object also gives access to the output stream object and the print writer object, which are used to flush output to the client. The output stream object is for binary data, and the print writer is for character data. If the output contains both binary data and character data, an output stream object should be used. Other Interfaces in Servlet 2.3This package contains a host of other interfaces relating to the following features:
The preceding three categories of interfaces complete the interfaces available as part of the javax.servlet package. These new interfaces were introduced as part of the expanding servlet functionality. All these interfaces will be dealt in detail when we take a detailed look at request dispatching, filtering, and event handling, respectively. HTTP Servlet APISo far in this section we've covered the base servlet APIs that comprise the javax.servlet package. Let's look at the most popular use of the servlets: HTTP protocol–based HTTP Servlet API. We already saw a simple HTTP servlet example. In this section, we'll look at the APIs that are extended from the javax.servlet package specifically designed for the HTTP protocol. The HTTP-based servlet classes are organized into the javax.servlet.http package. Figure 14.3 describes the relationship of the HttpServlet classes as against the Servlet interface and request/response objects. It does not list all the methods in the classes and interfaces, only the important methods. Figure 14.3. HttpServlet class relationship.HttpServlet ClassThe base class of all HTTP servlets is the abstract class HttpServlet. It extends from the GenericServlet class explained earlier in the section. The HttpServlet implementer's job is to make sure to implement at least one of the following functions to process the input request: All the supported HTTP methods were listed earlier in Table 14.2. For most practical applications, you'll have to implement only doGet() and doPost(); you won't have to worry about overriding default implementations for the other methods. The default implementation of doOptions automatically determines what HTTP options are supported when a servlet developer overrides a particular service handling method. For example, when a servlet overrides doPost(), the supported options are POST, HEAD, TRACE, and OPTIONS. Similarly, with doTrace(), the default implementation makes sure that a response with all the headers is sent to the trace request. The HttpServlet can also implement life cycle methods such as init() and destroy() for initializing parameters and cleanup operations, respectively. This abstract class also provides the getServletInfo() method that can be used to describe the servlet. The service() method can be implemented for processing all kinds of HTTP requests, including GET, POST, DELETE, and so on, doing so is generally not a good programming practice. We'll look at this aspect when we discuss writing servlets later in the chapter. The default service() method redirects the incoming request to the appropriate doXXX() method listed in Table 14.1. Like all servlet types, HttpServlet is multithreaded by default. But the developer has to take care of handling static variables and shared resources such as database objects and files. All access to these resources should be synchronized. This class also provides the utility method getLastModified(), which gives the last modified time of the given HttpServletRequest object. This can be used for managing an internal cache of a servlet's output. By using this, the container can check whether a requested page has changed, avoiding calling doGet() and doPost() and reducing server workload. If a page in the cache isn't expired, the browser can use it instead of getting a fresh one from the servlet. All doXXX() and service() take HttpServletRequest and HttpServletResponse objects as arguments. TIP As good programming practice, always use doXXX() (such as doGet() and doPost()) to implement the program logic instead of the service() method. If you want the doGet() and doPost() methods to have the same behavior, write doPost() with the required behavior and have doGet() call doPost(). HttpServletRequestThis interface that encapsulates the request parameters of the client extends ServletRequest interface of the javax.servlet package explained earlier. The responsibility of creating this object is with the servlet container, in our case, with WebLogic Server. It's passed as an argument to the service() and doXXX() methods. The methods defined by this interface can be classified into the categories defined in Table 14.5. Other utility methods, such as getMethod(), getPathInfo(), getPathTranslated(), and inherited methods from the base class, are not explained here. For a full list of the methods available as part of this class, refer to the servlet API documentation at http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/http/HttpServletRequest.html. We'll see a sample output of the preceding functions when we discuss the simple servlet example in the next section. We'll cover the session and the session-related methods in a separate discussion of implementing sessions in servlets. Apart from the methods listed earlier, the HttpServletRequest interface inherits the methods for attribute handling and parameters encapsulated in the request object. These methods can be grouped into the groups discussed in the following sections. Using AttributesServlets in the same Web application can communicate with each other through attributes. The ServletRequest interface provides a set of methods to retrieve and set attribute values to store customized request information. This method is used in conjunction with dispatching requests using RequestDispatcher. As explained earlier when we discussed the ServletContext interface, methods provided for attribute manipulation are
CAUTION The Java packages, such as java.*, javax.*, and sun.*, should not be used because these are specialized packages that are part of the JDK. Some useful attribute keys are javax.servlet.request.cipher-suite and javax.servet.request.key-size, which are predefined in the request. In an HTTPS request, there's a special attribute javax.servlet.request.X509Certificate, which returns an array of the SSL certificates that are associated with the request. The attribute values returned are an array of java.security.cert.X509Certificate, which defines the runtime implementation of the X.509 v.3 certificate. Content InterfaceThis interface provides a set of functions for reading content-related properties such as reading the content length (getContentLength()) and content type (getContentType()). If any character encoding is used in the request, getCharacterEncoding() returns the name of the encoding; otherwise, it returns null. Client and Request PropertiesIf the servlet needs to obtain information about the client or the request, we can use the following functions:
Reading Client InputThe getReader() and getInputStream() return the buffered reader and an input stream, respectively. The reader is used for reading the request as character data, and the input stream is used for reading the request as binary data. But these methods should not be mixed in reading the request. There are other functions for reading the parameters encapsulated in the request along with the associated values:
We already looked at using these functions while developing the first servlet we wrote earlier in the chapter. We'll look at them again when we implement a modified version of the SimpleServlet later in the chapter using some of the functions we've discussed. HttpServletResponseSimilar to the HttpServletRequest that extends the ServletRequest interface, this interface extends ServletResponse, which was explained earlier. HttpServletReponse is a special interface for providing HTTP-specific functionality in the servlet reply. It has methods that complement the request interface, such as the following:
This interface provides functions for setting error codes and statuses for the response. Before we look at these functions, let's look at some of the common status codes in Table 14.6.
For a full list of status codes, refer to the Sun Web site at http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/http/HttpServletResponse.html. Now let's look at the error functions that the ServletResponse interface provides:
The super interface of HttpServletResponse is ServletResponse, which was briefly touched on earlier. Let's look at some of the important methods that HttpServletResponse inherits from the super interface. The getOutputStream() and getWriter() functions return an output stream and print writer, respectively. The output stream is used when binary data, such as an image or GIF file, is sent back to the client. The print writer is used for sending character data back to the client. Some of the other included functions are getters for content length and buffer size, along with setters for content length, content type, and buffer size. There are also buffer manipulation functions such as resetBuffer() and flushBuffer(). Flushing a buffer means the response stream is now ready to send. It is said to be committed. We've already looked at using some of these functions in the first servlet we wrote earlier in the chapter. We'll look at some of the response-related functions and the output they create when we get to using the servlet API in the later part of the chapter. Servlet ExceptionsThe exception framework in the Servlet API consists of one basic class: javax.servlet.ServletException. This exception is thrown in all request-handling routines, such as service(), doGet(), doPost(), and so on. The IOException is also used in these routines in case of an input/output-related exception. Let's look again at the example of the GenericServlet in Listing 14.3. The service() method in that example throws ServletException and IOException. Exceptions can be embedded in other exceptions. For this case, ServletException provides a getRootCause() method that returns the Throwable object that caused the ServletException. UNAVAILABLE EXCEPTION This exception, which is a subclass of ServletException, is used when the servlet becomes unavailable—temporarily or permanently. The exception thrown provides an isPermanent() method to identify the type of unavailability. As a servlet container, WebLogic Server is capable of handling both temporary and permanent unavailability in the same fashion. This exception also provides a getUnavailableSeconds() method to find out the total downtime. |
[ Team LiB ] |