Servlet Design


A servlet represents a Java class running within a Java Virtual Machine (JVM) related to a web server. Servlets interact with a collection of JavaBeans or Enterprise JavaBeans (EJBs) to execute any described business logic. As previously stated, servlets add functionality by providing session management and other related functions such as user authentication and authorization. The following topics provide a framework for understanding a servlet’s responsibilities:

  • HTTP essentials

  • Servlet life cycle

  • Servlet primary classes

HTTP and Servlets

HTTP, which provides the basic services for the Web, is built on the TCIP/IP protocol and is employed for application-level data transmission. One of the primary beneficial characteristics of HTTP is its request-response protocol. It is the transmission protocol of choice because it facilitates transmission of data through corporate firewalls. It also allows requests and responses to exist as MIME-like messages.

From an application-level perspective, HTTP has its drawbacks. It is both stateless and connectionless. It is based on a web server and has the following format: it receives client requests and sends a response back to the client. It is important to understand that neither the client nor server retains any state information whatsoever. Incidentally, servlets take over where HTTP is unable to preserve state. Servlets support session state. A client can be one of the following:

  • A web-enabled browser

  • A Java applet

  • Another web server

  • Another web-enabled application

A servlet is accessed through a Universal Resource Locator (URL). A URL is specific to the HTTP scheme, but a URN is not. URLs exist as simple formatted strings that identify an object via name, location, or any other resource characteristic. HTTP does not place any limitations on a URL’s length. For example, in order to access a specified HTML page such as index.html residing on a web server such as www.dps.com, the absolute URL would be http://www.dps.com/index.html. The basic format for the URL is as follows:

protocol://hostname<:port>/identifiers

Servlets make extensive us of GET and POST requests. Let’s examine them. A GET request can be made in several ways:

  • Enter a URL in the URL line of a web browser.

  • Click on a link that appears inside an HTML page, for example, <A HREF=url . . .>.

  • Select a form button to submit your request. The form would specify a GET method with the following syntax: <FORM method=GET action= url…>. After receiving a client request, the web server maps it to a file residing on a web server file system (for example, C:\www.html\index.html) and then responds by returning the payload of that file to the browser. This transaction involves exactly one connection to the web server and a single response back to the client.

The POST round-trip request is as follows: Let’s say the request is for the URL http://webserver/servlet/Register. The user clicks the form’s button designated specifically for accessing a servlet in the format <FORM method=POST action=url…>. After receiving the request, the web server maps it to the servlet’s class file residing on a web server, or servlet engine file system such as C:\WebSphere\AppServerf\servlets\ Register.Class. The web server then runs the servlet. Next, the server or servlet engine parses the posted data, utilizing a second connection and performing the requested POST operation. Finally, the servlet engine or web browser responds with a result. This operation requires two separate connections to the web server with an immediate response.

Note

Sun Microsystems provides a reference implementation for the Java Servlet API named Tomcat. You can download Tomcat from http://www.apache.org. IBM’s VisualAge for Java supports servlet testing. It contains the WebSphere Test Environment (WTE), a servlet development and test environment based on IBM’s WebSphere. The WTE can be used in VisualAge for Java instead of Tomcat for developing and testing servlets.

The Servlet Life Cycle

The process of loading a servlet into memory, executing the servlet, and then unloading the servlet from memory is the servlet life cycle. For example, a servlet is accessed by typing the following URL: http://localhost/servlet/GreetingsServlet. Typing the keyword servlet in the URL path informs the web server that the client request is designated for a particular servlet and not an HTML page.

Creating a servlet requires the following steps:

  • Create a GenericServlet subclass, essentially the class javax.servlet.http.HttpServlet, meaning you invoke the servlet via HTTP.

  • Supply the minimum doGet() or a doPost() method to make the servlet workable. When the servlet is requested for the first time, the web server asks the servlet engine to load the designated server class and all of its methods into memory on the servlet engine node.

  • Pass control to the init() method. Note that GenericServlet provides a default empty init() method. Here is where you perform any initialization tasks, such as connecting to a database. The init() method receives only one initial call, which occurs immediately after the servlet is loaded into memory. The following code demonstrates how to write the init() method:

    public void init(javax.servlet.ServletConfig config) throws ServletException
    {super.init (config);
    // place your code here to perform any initialization tasks
    }

Each time a servlet is called, a new thread is created, and that thread executes over the service() method.

  • Override the service() method in order to perform any work. This method is where a servlet performs its multifarious tasks. Because the service() method is always executed within a new thread, make sure that everything executed within this method is reentrant (thread safe).

  • Finally, call the destroy() method when the web server senses that the servlet’s tasks are complete. The destroy() method unloads the servlet from memory. Typically, tasks such as closing database connections, closing files, and other administrative tasks are performed in this context.

A Small Servlet

Every text presents a HelloWorld example. Why display a complex example when simplicity is both more efficient and more informative? So let’s plunge in and examine this servlet:

/**
*This class is an example servlet
*/
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloServlet extends HttpServlet{
/**
*this method handles an HTTP GET request and outputs
*HTTP to print "Hello World" to the browser
*/
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException{
PrintWriter out = null;
res.setContentType("text/html");
out.println("<html>");
out.println("<head><title>A Servlet example</title></head>");
out.println("<body>");
out.println("Hello World!");
out.println("</body>");
out.println("</html>");
}
}

Assuming the localhost is properly defined, and the web server and application server are properly configured, type the following code in your browser: http:// localhost/servlet/HelloServlet.

The servlet class extends the class javax.servlet.http.HttpServlet. The main point to remember here is that HTTP servlets typically handle GET and POST requests. The HttpServlet subclasses override either the doPost() or doGet() method. In our example, we’re overriding the doGet() method.

An object that implements the HttpServletResponse() method achieves the following:

  • Procures a PrintWriter for output with getWriter(). This is preferable because PrintWriter performs like an output stream. An alternative to this is using the getOutputStream().

  • Sets the HTTP header values with setHeader(String, String). The chief benefit of this method is that it enables the developer to disable both browser and server page caching for a response page.

  • Redirects the browser to a different page using the following directive: sendRedirect(String).

  • Sets the content type with setContentType(String).

Servlet Interfaces and Classes

The Java Servlet API 2.1 offers developers an extensive set of classes and interfaces with which to develop web applications. APIs are contained within three distinct packages. The developer is required to supply implementations for these interfaces:

  • javax.servlet

  • javax.servlet.http

  • javax.servlet.jsp

The javax.servlet Package

The javax.servlet package represents a collection of basic APIs for servlets. However, they are not bound to any particular schema or protocol that defines how they should be implemented. Table 2-2 lists the classes and interfaces in the javax.servlet package.

Table 2-2: Classes and Interfaces in the javax.servlet Package

Classes

Interfaces

GenericServlet

RequestDispatcher

ServletException

Servlet

ServletInputStream

ServletConfig

ServletOutputStream

ServletContext

UnavailableException

ServletRequest
ServletResponse
SingleThreadModel

Servlet Interface

The Servlet interface defines the essential APIs for servlets that include the init(), service(), and destroy() methods.

Note

All servlets implement this interface by subclassing the GenericServlet class or, alternatively, the HttpServlet class.

ServletContext Interface

For each servlet, a context is required because communication must be established with a servlet in a nonrequest-specific manner. Requirements for this include locating path information, accessing different servlets running on a web server, and writing to the server log file.

Note

If a server supports multiple virtual hosts, the ServletContext object must be unique. The ServletContext object resides within the ServletConfig object. You can access this object by employing the Servlet.getServletConfig() method.

GenericServlet Class

This class is abstract and provides the primary behavior for the Servlet interface. This class also implements the ServletConfig interface, thereby offering a convenient way to access the ServletContext and initialization parameters. It also implements the init() and destroy() methods. All subclasses should override both the init() method and destroy() method and call the super-class implementation for the GenericServlet class.

ServletRequest Interface

The ServletRequest interface prescribes an object as the first parameter passed in a call to the service() method for a GenericServlet. This provides the servlet with metadata about the request originating from a client call. It includes data, parameter name, values, attributes, and an input stream. For example, the HttpServletRequest provides HTTP data. Furthermore, a servlet request represents a MIME body request. Conversely, the response provides a MIME body response. It is always wise to use the getReader() method when the body contains text. If the body contains binary data, use the getInputStream() method.

ServletResponse Interface

This interface defines an object used in transmitting MIME-encoded data from the servlet to a client. The servlet engine creates a ServletResponse object and transmits it as an argument in the servlet’s service method. Always call the SetContentType() method before calling either the getWriter() or the getOutputStream() method.

RequestDispatcher Interface

This interface defines an object that receives requests from a client and forwards them to a resource, such as a servlet, an HTML file, or a JSP file on the server. The servlet engine creates a RequestDispatcher object, which wraps a server resource residing on a specified path. The intent is wrapping servlets. However, a servlet engine can create RequestDispatcher objects to wrap any type of repository resource.

A RequestDispatcher is obtained from the ServletContext by utilizing the ServletContext.getRequestDispatcher(“resource-name”). Once the dispatcher is obtained, a servlet can forward the request to the named resource in getRequestDispatcher(). An alternative is to use RequestDispatcher() for sending a request to a Java Server Page for display.

Note

The RequestDispatcher() interface provides a convenient way for servlets to communicate among themselves.

The javax.servlet.http Package

This package hosts the APIs for servlets used as servlets. Table 2-3 lists the classes and interfaces in the javax.servlet.http package.

Table 2-3: Classes and Interfaces in the javax.servlet.http Package

Classes

Interfaces

Cookie

HttpServletRequest

HttpServlet

HttpServletResponse

HttpSessionBindingEvent

HttpSession

HttpUtils

HttpSessionBindingListener

NoBodyOutputStream

HttpSessionContext

NoBodyResponse

n/a

HttpServlet Class

The GenericServlet provides the basic behavior for a servlet. However, a separate mechanism for processing HTTP requests is essential. The HttpServlet, a subclass of GenericServlet, provides the additional behavior for HTTP requests. The GET and POST methods are most commonly used. HttpServlet includes the doGet() and doPost() methods for handling both HTTP GET and HTTP POST.

When an HttpServlet is requested via a URL, the service() method examines the HTTP header and determines which HTTP method to invoke. The programmer must provide overrides for doGet() and doPost() in order to achieve the servlet’s requested tasks. Both the service() and do() methods require two parameters, which represent instances of the HttpServletRequest and HttpServletResponse interfaces.

These versions of the request and response objects contain HTTP-specific items such as cookies, headers, and sessions.

HttpServletRequest Interface

This interface extends the ServletRequest interface by defining a request object associated with the HTTP request. Special items included in this category are authentication through the getAuth() method, the list of cookies through the getCookies() method, and the query string through the getQueryString() method. The servlet engine implements this interface.

HttpServletResponse Interface

This interface extends the ServletResponse interface and defines a response object corresponding with an HTTP response. This interface permits the servlet’s service() method both to access and set HTTP headers and to return data (HTML) to a client.

HttpSession Interface

This interface establishes an application-level connection between the web browser and the web server. Utilizing sessions enables the developer to store session-specific data in the servlet engine. The session persists for a specific time period spanning more than one connection or page request from the user. Typically, a session corresponds to a single user who may visit the same site repeatedly. The server can maintain a session by leveraging the services of a cookie or by rewriting URLs.

HttpUtils Class

This interface represents a concrete class providing a collection of methods that a developer can use when creating HttpServlet subclasses. The getRequestURI() method, a static method, facilitates the ability to reconstruct the request URI for use by the server.

Nonstatic methods include parsePostData(), for parsing the parameters of a POST, and parseQueryString(), for parsing a GET request’s query string.

Managing Session State with Servlets

As a developer, one of the biggest challenges is maintaining an identity with users as they revisit your site multiple times. The information collected during these visits is called session data. Making the distinction between session data and transaction data is easy. Session data is temporary, whereas transaction data is persisted in a repository such as DB2 or Oracle. You can easily convert session data to transaction data by using an interface provided by the Java Servlet API. As each session is created, it is assigned a unique identifier. The ID is subsequently associated with the user and becomes the key ultimately used for locating the proper session for subsequent visits.

The HttpSession interface facilitates both storing and retrieving application state information. To begin, an instance of the HttpSession is procured through the HttpServletRequest interface. The required interface method is the HttpSession getSession(boolean). The Boolean argument, if determined to be true, creates a new session. Many times, it is desirable to ascertain whether the HttpSession returned was in fact a newly created session or one previously created. Accomplish this by using the HttpSession interface method boolean isNew(). It returns a Boolean to indicate whether the sessionID was returned in the current HttpServletRequest object. It is also possible to discard a session by using the void invalidate() method.

An alternative to storing key-value pairs is placing objects in a session instance by employing the void putValue(String, Object) method and retrieving objects from the current session by using the Object getValue(String).

Here is an example demonstrating how to employ these methods. International Foreign Currency Exchange maintains a staff of employees for implementing the business model. In this example, IFCE has designed an Employee Editor set of servlets to facilitate changing employee attributes. The user first enters an employee ID on an HTML page, followed by another HTML page displaying the current values of the employee’s attributes. They are modifiable and should be resubmitted with new values. The first servlet called is the DisplayEmployeeValues, where an employee ID is retrieved.

public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException{
String id=request.getPararameter("id");
Employee emp = Employee.getEmployeeFor(id);
HttpSession session = request.getSession(true);
/*check to see if the session is new.
If not true, invalidate the current session and create a new session */
if(session.isNew()==false){
session.invalidate();
session=request.getSession(true);
}
session.putValue("employee",emp);
}

Assume the user has decided to submit the changes. Clicking the Submit button invokes another servlet to process the modifications and persist any data modifications.

public void doPost(
HttpServletRequest request,
HttpServletResponse response
)throws ServletException, IOException{
HttpSession session =request.getSession(false);
if(session== null)
handleError();
else {
Employee emp =(Employee)session.getValue("employee");
if(emp != null)
{
session.invalidate();
}
//send a response
}

The preceding example demonstrates how to procure an existing session from the request object. The false parameter in the getSession() method specifies not to create a new session if one is not located in the request object. If so, a null is returned. The getValue() method return type is Object, so the value must be cast to the appropriate type before the value is usable.

Determining How a Session Is Located

When the HttpServletRequest.getSession() method is invoked, the application server ascertains which HttpSession instance is associated with the current user by assigning a session identifier. This identifier is stored in a specified cookie in the user’s browser.

Note

Session cookies are not in permanent storage and expire when the browser closes. An application server’s JVM initially holds the HttpSession in memory. Only the identifier is stored in the client’s browser.

As long as cookies are enabled in a client’s browser, they serve as the conduit for transporting the session identifier between browser and server. On the other hand, if cookies are not available, URL rewriting is a viable option. In order to accomplish this, employ the encodeURL() or encodeRedirectURL() method from the HTTPResponse interface. The former method appends the unique session ID to the URL in any links generated by your servlet. For example, when a user invokes a servlet using the modified URL, the server strips the ancillary information from the URL and utilizes it as the new session ID for retrieving the session data.

Another high-scale solution for persisting session data is storing HttpSessions in a third-tier relational database shared by multiple JVMs. Here is how it works. Each HttpSession represents a transaction in a third-tier relational database. The transaction begins with a call to the HttpServletRequest.getSession(). The session is terminated when either the servlet’s service() or sync() method is called on the class that implements HttpSession in a container such as WebSphere.




.NET & J2EE Interoperability
Microsoft .NET and J2EE Interoperability Toolkit (Pro-Developer)
ISBN: 0735619220
EAN: 2147483647
Year: 2004
Pages: 101
Authors: Simon Guest

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