Engineering Full Stack Apps with Java and JavaScript
A servlet is a java class that conform to the servlet specification and need to be deployed to a servlet container to work as a servelt.
Below is the hierarchy of HttpServlet class:
Interface javax.servlet.Servlet
abstract class javax.servlet.GenericServlet implements Servlet, ServletConfig, Serializable
abstract class javax.servlet.HttpServlet extends GenericServlet
A servlet is responsible for handling requests and most of the processing required by a web application. A servlet is a java class that implements the interface javax.servlet.Servlet.
The abstract class GenericServlet contains protocol independent implementation of some maintenance code useful for all servlets.
The abstract class HttpServlet contains HTTP specific implementation and all HTTP-based servlets extend this.
A servlet's methods are called in a particlular order and at particular times by the servlet container, and this sequence is known as the life cycle of servlets.
A servlet’s life cycle consist of:
Servlet class loading - the point where static data (if any) in your servlet are initialized
Servlet instantiation - the point where instance data (if any) in your servlet are initialized, and the no-argument constructor (if present) is called. The servlet must be loaded and instantiated before the first request for it is processed.
init() - the initialization method called when a servlet instance is created.
service() - the method called to perform the work. The service() method convert HTTP requests into appropriate doXXX() method calls.
destroy() - When a servlet instance is taken out of service, the destroy() method is called—only once for that instance.
Class loading
Each application has its own class loader and servlets are loaded just like any other class by the class loader for that application.
Instantiation
Container will call the no argument constructor for instantiating a servlet. Hence, you should either not provide any constructors or if there are any argument constructors, then you should provide an explicit no argument constructor.
The init method
The servlet is initialized by calling the Servlet's init(ServletConfig) method implemented in the GenericServlet. GenericServlet also has an overlaoded method init() that does not take any parameters. The init(ServletConfig) of GenericServlet stores the ServletConfig object it receives from the servlet container for later use. It then makes a call to init(). The init() method is a convenience method in the GenericServlet class which we can override and write our initialization code. You can even override init(ServletConfig), but you are then responsible for calling super.init(config) and storing the ServletConfig object it received. Also, init() will not be called in this case, unless your implementation of init(ServletConfig) calls it.
The servlet container is guaranteed to call init method once, and only once, on instantiation of the servlet. The init method must complete successfully before the servlet container will allow any requests to be processed by the servlet.
The init() method might throw a ServletException, or it might run out of time. A ServletException is a failure, and the servlet container can abandon this instance and try to construct another. An init() method can also throw UnavailableException which is a sub class of ServletException, in which case container can make additional attempts.
Initialization code for a servlet could even go in the constructor. There’s nothing wrong in having a zero-argument constructor for a servlet, but it’s more usual to override the public void init() method and place initialization code there.
The service method
The service method is called by the servlet container for every client request. Multiple threads may simultaneously access the service() method for a single servlet instance.
The service method is defined in the Servlet interface and is implemented by the GenericServlet and HttpServlet classes. This method accepts a ServletRequest and ServletResponse as parameters.
void service(ServletRequest req, ServletResponse res)
There is an overloaded version of the service method in HttpServlet that accepts an HttpServletRequest and HttpServletResponse. The service method in the HttpServlet that accepts ServletRequest and ServletResponse dispatches client requests to the protected service method that accepts HttpServletRequest and HttpServletResponse:
protected void service(HttpServletRequest req, HttpServletResponse resp)
This method dispatches the request to appropriate doXXX() methods corresponding to the seven HTTP methods. These doXXX methods have the same name as the seven http methods with a “do” in front (e.g., doPost() for POST).
According to the spec, you should always override doGet, doPost, doPut and doDelete if you need to use those methods; else it will throw 400 ('Bad Request') in case f HTTP/1.0 and 405('Method Not Allowed') in case of HTTP/1.1. The doHead call doGet, discard body and return the header. The doOptions and doTrace do not need to be overriden unless there is a specific requirement for a trace procedure.
The destroy method
When a servlet instance is taken out of service, the destroy() method is called (only once) for that instance and we can write any cleanup code for the servlet. It takes no arguments and throws no exception. The servlet spec says that once the destroy method is called on a servlet instance, the container may not route other requests to that instance of the servlet and if the container needs to enable the servlet again, it must do so with a new instance of the servlet’s class. The destroy() method is never called if init() had failed.
The servlet spec says nothing about when destroy will be called, so the developer should not make any assumptions about when (and how often) it might happen. The servlet container is not required to keep a servlet loaded for any particular period of time. When the servlet container determines that a servlet should be removed from service, it calls the destroy method to allow the servlet to release any resources it is using and then make it available for garbage collection. However the servlets container should make sure that all threads executing a service() method on this instance have ended or if not ended, gone beyond a server-defined time limit.
1. Can we have servlets with parameterized constructor?
We can have servlets with parameterized constructor, provided we also have a no argument one. This is because containers will instantiate servlets only using the no argument constructor. If we don’t provide a constructor, java will provide a default contructor. However if we provide a constructor with arguments, container won’t provide the default no arg one and hence won’t be able to find a no-arg constructor and instantiate a servlets; and we will get a java.lang.InstantiationException.