Servlets provide a way to communicate with client requests and generate dynamic responses based on the request-response programming model. Servlets can respond to any type of request but in most cases, these are used in web applications hosted by web servers. For these applications, Java Servlets define HTTP – specific servlet classes. For writing Servlets, Java Servlet API provides interfaces and classes in javax.servlet and javax.servlet.http packages. The servlet interface defines the life cycle of the servlet. We must extend GenericServlet class or HTTPServlet class(specific to HTTP request/response) to handle the client requests in web applications.
Flow of Execution of Servlets
In the execution of a servlet for the provided client request, the servlet container plays a crucial role in the Servlet life cycle.
Servlet container:
It is a web container that is part of a web server that interacts with the Java Servlets. Servlet container is responsible for
- Managing the lifecycle of servlets
- Creating servlet object, request, and response objects
- Mapping a URL to a particular servlet
- Ensuring that the URL requester has the correct access rights
- Managing the execution of JSP pages etc,
Before an application client component can be executed, it should be deployed into the container. All these web components and the container runs on the web/application server.
Servlet Program:
To understand the flow of execution of the servlet, we will create a simple web application to display the hello message in the client browser. In this example, we will be using Eclipse IDE and Tomcat server. Create the following files as shown in below package directory structure.
Example
Files to create:
- Create “Dynamic web application” project in Eclipse.
- Create “index.html” file to take input from the client in the request.
- Create “HelloServlet.java” to process the request and generate the response.
- Create “web.xml” file to specify the URL mapping to the respective servlet.
index.html:
Create the below form to take the user name as input from the client browser.
HTML
<!DOCTYPE html> < html > < head > < meta charset = "ISO-8859-1" > < title >Home</ title > </ head > < body > < form action = "hello" method = "post" > Enter your name and click on submit: < input type = "text" name = "name" /> < input type = "submit" /> </ form > </ body > </ html > |
HelloServlet.java:
Create below servlet to accept the client request, process it, and generate the response.
Java
package com; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get the client entered data from request object String name = request.getParameter( "name" ); // set the response content type response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); // Print hello message to the client browser in // response object out.println( "<h3>Hello " + name + "!!</h3>" ); out.close(); } } |
web.xml:
Create deployment descriptor – web.xml file to mention the welcome file and to map the URL to the Servlet class.
XML
<? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation = "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id = "WebApp_ID" version = "3.1" > < display-name >ServletFlow</ display-name > < welcome-file-list > < welcome-file >index.html</ welcome-file > </ welcome-file-list > < servlet > < servlet-name >HelloServlet</ servlet-name > < servlet-class >com.HelloServlet</ servlet-class > </ servlet > < servlet-mapping > < servlet-name >HelloServlet</ servlet-name > < url-pattern >/hello</ url-pattern > </ servlet-mapping > </ web-app > |
Program Execution
- Right-click on the project, “Run As -> Run on server”
- While the start of the server, the web application will be deployed on the server.
Step 1:
Following is the conceptual diagram of the servlet container after the deployment of the application.
As shown in the above diagram,
At server side:
- Servlet container is available in the Main server and the web application is deployed into a servlet container.
- Inside the container, we have below folder structure.
- Web application – In this example, “ServletFlow”
- Inside that WEB-INF folder – we have URL mapping to the servlet name.
- Inside WEB-INF, web.xml file and classes folder to maintain .class file of “HelloServlet.java”
At client side:
- A browser will be available to send the client data in HTTP request and receive the HTTP response from the server.
- The protocol will establish a virtual socket connection between client and server based on IP address and port number.
Step 2:
When we start the server, the job of the servlet container is to
- Recognize all the web applications
- Deploying those web applications and
- Prepare a separate object for each application. This object is “servletContext” object.
While deploying web applications,
- The container will recognize the web.xml file under the WEB-INF folder.
- After identifying the web.xml file, the container will perform web.xml file loading, parsing, and reading the contents of it.
- If any application-level data like display names or context parameters are available in the web.xml file, the container will take that application data and store it in “servletContext” object. This data is managed by a servlet context object.
Now, the container will identify the welcome file page to display on the client browser based on the “welcome file list” mentioned in the “web.xml” file. Here, we specified, “index.html” as a welcome file. So, it displays that HTML page to the browser. URL: http://localhost:8081/ServletFlow/
Once we enter the name and click on submit, then a request will come to protocol with the data entered by the client.
Step 3:
- The protocol will prepare request format, it has 2 parts, Request header, and Request body.
- The request header contains the details about the client browser.
- For ex: Request Method type, Protocol information, Languages accepted by the client browser, cookies information Encoding mechanisms supported by the client browser, etc,
- The actual data entered in the user form will store in the Request body in form of request parameters.
- The protocol will carry this Request format to the main server.
- Then the server will check whether the request is valid or invalid.
- If it is valid, it will forward that request to the servlet container.
- Now, the container will identify what is the application name and resource name to execute.
- The container will check if the request is an HTML request based on the extensions and resource names.
- As we specified in the form, the container will identify the servlet to execute based on the URL pattern(“hello”) that associated is with the “HelloServlet.class” file under the classes folder.
- To identify it, the container will go for application, WEB-INF folder, and web.xml file.
- In the web.xml file, mapping details are available. so the container will get that particular servlet based on URL-pattern and then the container will look into the classes folder and search for the required .class file.
- Once the container identifies the servlet .class file, the life cycle of the servlet will start.
Step 4: Servlet Life cycle
Servlet Loading:
- The first container will perform Servlet Loading.
- The container will check if the same servlet is already available or not, if not then it loads the .class file, the byte code into the memory.
- To perform this, container will call class c = class.forName(“helloServlet”); internally.
Servlet Instantiation:
- After servlet loading, it creates an object for the servlet.
- And it creates “servletConfig” object for that servlet and stores all the data of that particular servlet in it.
- To perform this, container will call object obj = c.newInstance(); internally.
Servlet Initialization:
- Now we need to initialize the servlet, the container will call the init() by passing servletConfig object to it.
- First, the container will execute parameterized init() method. Inside that, another parameter less init() method will be called from the Generic servlet and that method also will be executed.
- Now, the container will create HTTP Request and HTTP response objects and a thread to execute dopost() method.
- In the case of GenericServlet, the first container will call the service() method in generic servlet, bypassing servlet request and servlet response objects as parameters.
- Here, as this is HTTP specific request, we are using HTTPServlet and we need to execute the doPost() method by passing Http servlet request and Http servlet response.
- Then container will access the doPost() method. Finally, that request comes to the dopost() method of the servlet.
- The purpose of the HTTP request object is to store the data specified by the client. It mainly 3 types of data, Request headers, Request parameters data, and Request attributes data.
- Request headers: To store the information about the client browser.
- Request parameters data: To store the actual information entered by the client for processing.
- Request attributes data: To store any dynamic data that is generated while executing the servlet.
- Once the “doPost()” method is executed, then the response will be generated in the response object.
- When the container reaches the end of the doPost() method execution, that thread will be destroyed and the container will dispatch that response to the main server.
- The main server will transfer the HTTP response to the protocol.
- The protocol will prepare a Response format that is having Response Header and Response Body.
- Response header: It contains metadata like which type of response is coming, length of that response, etc.
- Response Body: Actual dynamic response to be displayed in the client browser.
Step 5:
- The protocol will carry that response object to the client browser.
- The browser will get the data from the Response body and is displayed in the browser.
- When the response is displayed on the client-side, then the protocol will destroy the connection between the client and the server.
- Then container will understand the response is dispatched to the client and it will destroy the request object and response objects.
- Now the container will be in waiting for the state for further requests.
- Depending on container implementation and based on the application servers, the container will destroy the servlet.
- For Ex: In the case of the Tomcat server, the container will wait until the shutdown of server. In the case of the Weblogic server, it will wait for the time specified in the server.
- So, when the job is done by the application and the server is stopped, the container will destroy the servlet config object and then the servlet object.
- Destroying a servlet object is nothing but, de-instantiating the servlet by calling the destroy() method.
- The container will unload the servlet byte code from the memory and destroy the “ServletContext” object.
Conclusion
Java Servlets don’t have a main() method. It’s the job of Servlet Container for instantiating the servlet or creating a new thread to handle the request and response objects. To process multiple requests in a single servlet the container creates multiple threads. You can also monitor and react to these events in a servlet’s lifecycle by defining listener objects. The methods in listener objects get invoked when lifecycle events occur.