The lifecycle of a Java servlet follows a very logical sequence. The interface that declares the lifecycle methods is the javax.servlet.Servlet interface. These methods are the init(), the service(), and the destroy() methods. This sequence can be described in a simple three-step process:
1. A servlet is loaded and initialized using the init() method. This method is called when the servlet is reloaded or upon the first request to this servlet.
2. The servlet then services zero or more requests. The servlet services the request using the service() method.
3. The servlet is then destroyed and garbage-collected when the web application containing the servlet shuts down. The method that is called upon shutdown is the destroy() method.
The init() method is where the servlet begins its life. This method is called immediately after the servlet is instantiated, and it is called only once. The init() method should be used to create and initialize the resources that it will be using while handling requests. The init() method’s signature is defined as follows:
public void init(ServletConfig config) throws ServletException;
The init() method takes a ServletConfig object as a parameter. This reference should be stored in a member variable so that it can be used later. A common way of doing this is to have the init() method call super.init() and passing it the ServletConfig object.
The init() method also declares that it can throw a ServletException. If, for some reason, the servlet cannot initialize the resources necessary to handle requests, it should throw a ServletException with an error message that signifies the problem.
The service() method services all requests received from a client using a simple request/response pattern. The service() method’s signature is:
public void service(ServletRequest req, ServletResponse res) throws ServletException,IOException;
The service() method takes two parameters, the first of which is a ServletRequest object that contains information about the service request, encapsulating information provided by the client. The ServletResponse object contains the information returned to the client.
You will not usually implement this method directly, unless you extend the GenericServlet abstract class. The most common implementation of the service() method is in the HttpServlet class. The HttpServlet class implements the servlet interface by extending GenericServlet. Its service() method supports standard HTTP/1.1 requests by determining the request type and calling the appropriate method.
This method signifies the end of servlet’s life. When a web application is shut down, the servlet’s destroy() method is called. This is where all resources that were created in the init() method should be cleaned up. The signature of the destroy() can be found in the following code snippet:
public void destroy();
ServletRequest and ServletResponse
Interfaces ServletRequest and ServletResponse are two key abstractions of the client request to the server, and a server response to the calling client in Servlet API. For every request that comes to the server, servlet container will create instance of ServletRequest and ServletResponse and pass them on as arguments to the Servlet.service(..) method.
ServletRequest and HttpServletRequest
ServletRequest object will contain all information collected from the client request so they are accessible to the servlet that processes it, such as a protocol used to receive a request, remote clients IP address and port, content type, language, and the like. Collection of request parameters passed on from the client is stored in ServletRequest object as well. Each parameter consists of the key-value pair, where the key is the name of the parameter, and the value is the parameter value. Similarly, ServletRequest has the collection of request attributes as key-value pairs of attribute names and values. While ServletRequest parameters are passed on from the client initiating the request, ServletRequest attributes are objects stored explicitly by the servlet container component itself, so they are available for inspection in the later stages of servlet lifecycle. In addition, request parameters values are always Strings, while request attributes can be objects of any Java type.
Servlets are designed to be protocol independent, so the ServletRequest abstraction can be applied for request-response communication using any protocol. HTTP is the most widely used protocol for client-server communication over the Internet. For HTTP protocol-based request-response communication, the Servlet API defines interface javax.servlet.http.HttpServletRequest, which extends the ServletRequest interface.
The HttpServletRequest interfaces allows access to the HTTP-specific content of the request, like request HTTP method, HTTP headers, cookies, session information, and so on. Because it extends ServletRequest, all methods defined in ServletRequest are also available in HttpServletRequest objects. The concrete implementation and instantiation of the ServletRequest and HttpServletRequest interfaces are the responsibility of the servlet container. Tomcat, for example, implements HttpServletRequest interface in the org.apache.catalina.connector.Request class, and Tomcat supplies instances of that class internally to all servlets to conform to Servlet API.
ServletResponse and HttpServletResponse
The ServletResponse interface defines the methods to access the data that will be sent back to the client by the servlet container. Two main methods defined on the ServletResponse interface are getOutputStream() and getWriter().
Method getOutputStream() returns the instance of ServletOutputStream, which servlet developers can use to write binary content to, which is sent back to server. Using this method, you can implement servlets that trigger downloads of binary files like music, video, or documents Method getWriter() returns the instance of PrintWriter, which developers can write text-content to, which the servlet container will send back to the client to be rendered. Using this method, you can write the HTML content to the returned PrintWriter in the servlet class.
Just like ServletRequest, this interface is protocol independent, and it’s the responsibility of concrete implementations to use the required protocol details. Because HTTP is the main target protocol for servlets, Servlet API defines HttpServletResponse interface that in turn defines the methods to access information that will be sent to the client over HTTP protocol, including methods to add headers, cookies, status codes, and other HTTP-specific data to the response that will be sent to the client.
The GenericServlet and HttpServlet Classes
The two main classes that extend the servlet architecture are the GenericServlet and HttpServlet classes. The HttpServlet class is extended from GenericServlet, which in turn implements the Servlet interface. When developing your own servlets, you’ll most likely extend one of these two classes.
When extending the GenericServlet class, you must implement the service() method. The GenericServlet.service() method has been defined as an abstract method to force you to follow this framework. The service() method prototype is defined as follows:
public abstract void service(ServletRequest request, ServletResponse response) throws_ServletException, IOException;
The two parameters that are passed to the service() method are ServletRequest and ServletResponse objects. The ServletRequest object holds the information that is being sent to the servlet, and the ServletResponse object is where you place the data you want to send back to the client. In contrast to the GenericServlet, when you extend HttpServlet, you don’t usually implement the service() method. The HttpServlet class has already implemented the service() method for you. The following prototype contains the HttpServlet.service() method signature:
protected void service(HttpServletRequest request, HttpServletResponse response) throws_ServletException, IOException;
When the HttpServlet.service() method is invoked, it reads the method type stored in the request and uses this value to determine which HTTP-specific methods to invoke. These are the methods that you want to override. If the method type is GET, it calls doGet(). If the method type is POST, it calls doPost(). Although the service() method has five other method types associated with it, we are focusing on the doGet() and doPost() methods. Below table shows all HTTP methods and the corresponding methods of HttpServlet class that you need to override.
You may have noticed the different request/response types in the service() method signature of the HttpServlet as opposed to the GenericServlet class. The HttpServletRequest and HttpServletResponse classes are just extensions of ServletRequest and ServletResponse with HTTPspecific information stored in them.
The HttpServlet.service() method implementation is a convenient way to control access to your servlets in the code. For example, servlets that delete data from the database should always be accessed using the DELETE method, but because browsers only support GET and POST operations, the POST method should be used instead. If the DELETE operation is exposed using the doGet() and GET method, search engine crawlers, which follow all links on a web page using GET method, would be able to delete the data by simply visiting the link. But if you extend HttpServlet to implement your data-deleting servlet, you can leave doGet() method unimplemented, and search engine crawlers will not be able to access it.