What is Servlet?
Servlet is a Java program that is running on a web server in Servlet Life Cycle. Servlets are used to create a dynamic web application. The dynamic web application content can be changed depends on a specific request that was sent to the server. This is the main benefit in comparison with a static web application.
All the interfaces and classes dedicated to Servlets creation and work with them are in two packages javax.servlet and javax.servlet.http.
The last version of the Servlet API is Servlet 4.0. It was released together with the Java Enterprise Edition 8. There was added support of HTTP/2 and Server Push. Servlets are portable, efficient, scalable, robust.
Before starting with the life cycle of Servlet, we need to review a few terms that you will often encounter in this article. It will help you to understand things faster.
Web Server is an 1that handles HTTP Requests by a client and responds to the request with an HTTP Response.
Web Container is also known as Servlet Container or Servlet Engine. It is the main component of a Web Server that interacts with Servlets. It is responsible for managing the life cycle of Servlets.
Servlet Interface methods
When you want to develop a servlet you have to implement the interface javax.servlet.Servlet. A servlet is a Java code loaded into and runs inside a servlet engine, a web server. It receives requests from clients and responds to them. For example, a client can request information from a database. A Servlet can receive the request, get data needed by the client from a database, and then returns it to the client.
The Servlet interface has just several methods that are known as life-cycle methods. They are dedicated to initializing a servlet, to receive and respond to client requests, and to destroy a servlet with its resources. And also there are some additional methods. Let’s take a look at them:
Method to initialize the servlet:
void init(ServletConfig config) throws ServletException
The method is called by the servlet engine and finishes before any service requests are accepted. The config object contains the servlet configuration and initialization parameters. This method saves the ServletConfig object. After, you can get this object by the getServletConfig method:
ServletConfig getServletConfig()
The next valuable method in the Servlet interface is the method responsible to handle a single request from the client:
void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
The request contains information about the service request with parameters provided by the client. The response encapsulates and returns information to the client.
Service requests are handled after the servlet initialization has completed. The servlets typically run inside multi-threaded servers that can process multiple service requests simultaneously. If you write a Servlet you have to synchronize access to any shared resources.
There is a method that returns a string containing information about the servlet:
String getServletInfo()
It can return servlet author, version, copyright. This method can be called to display information in an administrative tool. This string that method returns have to be plain text and not contain markup.
The last method from the Servlet interface is a method to destroy Servlet:
abstract void destroy()
It does not have parameters. It cleans up all resources, such as memory, handlers for files, threads. This method makes sure that any persistent state is synchronized with the current in-memory state of the Servlet. The method is called once and automatically, during the unload.
Life Cycle of a Servlet
The life cycle of any Servlet has five stages. Initially, you need to load the Servlet class and create an instance of it. After, you need to invoke the Servlet method init(). Those three steps are executed just one time when the servlet is initially loaded. By default, the servlet is not loaded until the first request is received for it. But you can force the container to load the servlet when the container starts up. You can configure this behavior in web.xml Servlet Configuration.
After initialization, the Servlet method service() is invoking for each client’s HTTP request.
Eventually, the destroy() method on your Servlet. It is executed when the servlet container unloads the servlet.
Load Servlet Class
When the webserver starts up, the servlet container is deploying. It loads all the servlets because before a servlet is invoked the servlet container must first load servlet class definition. This is implemented the same way like any other class is loaded. An example of a web server is Apache Tomcat, Jetty, Apache TomEE, Oracle WebLogic, WebSphere, Apache Geronimo, etc.
Create Instance of Servlet
The second step once all the Servlet classes loaded, the servlet container creates instances of each servlet class. Usually, the Servlet container creates only one instance per servlet class. All the requests coming to the servlet are executed concurrently on the same servlet instance. This is up to the servlet container to decide the number of instances. But typically, there is just one instance.
Invoke the Servlet init() method
Once all the servlet instances are created, the servlet container invokes the init() method for each instantiated servlet. There is some set of parameters to init that is used to initialize the servlet. You can specify them in the deployment descriptor file(web.xml).
For example, there is the element load-on-startup in web.xml for Servlet. This property you can use to define the situation when the servlet will be loaded by the servlet container. Without this element, the servlet will be loaded when the first request arrives.
Invoke the Servlets service() Method
After loading and initialization of servlets, a web server is ready to receive a request. When a web server receives a request for a particular Servlet, the service() method of that Servlet is invoked. If your Servlet is the subclass of the class GenericServlet then the request is served by the service() method itself. If the Servlet is a subclass of the class HttpServlet then service() method receives the request and decides the correct handler method based on the type of request.
For example, if your Servlet got a Get Request the service() method would dispatch the request to the doGet() method with request parameters.
Each type of request (Post, Head, Put, etc.) is dispatched by service() method of the servlet to the corresponding handlers doPost(), doHead(), doPut(), etc.
This servlet life cycle step can be executed zero or multiple times.
Call the Servlets destroy() Method
And eventually, a servlet can be unloaded by the servlet container. In this situation, its destroy() method is called. This step of a servlet life cycle can be executed only one time.
A servlet can be destroyed by the container when the container shuts down. One more reason to destroy a servlet can be that the container reloads the whole web application at runtime.
Servlet Example
Servlets Hierarchy
The Servlet interface has three known implementing classes. they are FacesServlet, GenericServlet, HttpServlet.
FacesServlet is a servlet that manages the request for web applications that are utilizing JavaServer Faces to construct the user interface.
GenericServlet defines a generic, protocol-independent servlet. It implements the Servlet and ServletConfig interfaces. The use of GenericServlet makes writing servlets easier. This class provides simple versions of init and destroy, which are lifecycle methods. GenericServlet also implements the log method from the ServletContext interface.
To create a generic servlet, you need to override just one abstract method service().
HttpServlet is an abstract class, the most known of Servlet types. It helps to create an HTTP servlet suitable for a Web site. If you create a subclass of HttpServlet, you have to override at least one of the methods, that can handle a particular type of request. They are
- doGet, if the servlet supports HTTP GET requests;
- doPost, for HTTP POST requests;
- doPut, for HTTP PUT requests;
- doDelete, for HTTP DELETE requests;
There’s almost no reason to override basic methods of a servlet life cycle, such as init, destroy. the same as doOptions and doTrace methods.
Implementation
If your application is using Maven, you have to insert into pom.xml this dependency:
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>
Let’s create our first HttpServlet:
package servlet.testservlet; import java.io.*; //Import required java packages for work on Servlets import javax.servlet.*; import javax.servlet.http.*; // we are extending HttpServlet class public class ServletExample extends HttpServlet { private String message; public void init() throws ServletException { // Here we are doing all required initialization message = "Hello from our Fiest Servlet"; } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Set response content type response.setContentType("text/html"); PrintWriter out = response.getWriter(); // we are building a response out.println("<h3>" + message + "</h3>"); } public void destroy() { // do nothing, we don't have resources to release } } }
In the current example, the destroy() method can be skipped. If nothing to initialize, we can also skip the init() method. Our servlet can handle HTTP GET requests. We can design a servlet that can answer to all types of HTTP requests, by implementing also doPost, doPut, doDelete methods.