How do servlets work?
Categories:
Understanding How Servlets Work in Java Web Applications

Explore the core mechanics of Java Servlets, from their lifecycle and request handling to their role in dynamic web content generation.
Servlets are fundamental components of Java web applications, acting as server-side programs that extend the capabilities of web servers. They are primarily used to process client requests and generate dynamic web content. Unlike traditional CGI scripts, servlets are persistent, running within a servlet container (like Apache Tomcat or Jetty), which provides a more efficient and robust environment for handling web traffic. This article delves into the inner workings of servlets, explaining their lifecycle, how they handle requests, and their interaction with the web server.
The Servlet Lifecycle
Every servlet instance follows a well-defined lifecycle managed by the servlet container. This lifecycle consists of three main phases: initialization, service, and destruction. Understanding these phases is crucial for developing robust and efficient servlets. The container is responsible for creating servlet instances, invoking their methods, and eventually destroying them.
stateDiagram [*] --> Uninitialized Uninitialized --> Initialized: init() Initialized --> Ready: init() completes Ready --> Ready: service() (multiple times) Ready --> Destroyed: destroy() Destroyed --> [*]
Servlet Lifecycle State Diagram
Initialization Phase
When the servlet container starts or when the first request for a servlet arrives (depending on configuration), the container loads the servlet class and creates an instance. Immediately after instantiation, the container invokes the init()
method. This method is called only once throughout the servlet's lifetime and is used for one-time setup tasks, such as establishing database connections or loading configuration parameters. It's important to note that if init()
throws an ServletException
, the servlet will not be put into service.
Service Phase
After successful initialization, the servlet is ready to handle client requests. For every client request, the servlet container invokes the service()
method. This method determines the type of HTTP request (GET, POST, PUT, DELETE, etc.) and dispatches it to the appropriate doGet()
, doPost()
, doPut()
, doDelete()
, or other doXxx()
methods. These doXxx()
methods contain the core logic for processing the request and generating the response. A single servlet instance can handle multiple concurrent requests, making thread safety a critical consideration during development.
Destruction Phase
When the servlet container is shut down, or when the servlet is no longer needed, the container invokes the destroy()
method. Like init()
, this method is called only once. Its purpose is to perform cleanup tasks, such as closing database connections, releasing resources, or saving state. After destroy()
completes, the servlet instance is garbage collected.
doGet()
and doPost()
(or other doXxx()
methods) instead of service()
directly, as HttpServlet
's service()
method handles the request dispatching for you, simplifying your code and ensuring proper HTTP method handling.Request and Response Handling
The primary function of a servlet is to process client requests and generate responses. This interaction is facilitated by two key objects passed to the service()
method (and subsequently to doGet()
, doPost()
, etc.): HttpServletRequest
and HttpServletResponse
. These objects provide access to all the information related to the client's request and allow the servlet to construct the response.
sequenceDiagram Browser->>Web Server: HTTP Request Web Server->>Servlet Container: Forward Request Servlet Container->>Servlet: service(HttpServletRequest, HttpServletResponse) Servlet->>Servlet: Process Request (doGet/doPost) Servlet->>Servlet: Generate Response Content Servlet->>Servlet Container: Send HttpServletResponse Servlet Container->>Web Server: Send HTTP Response Web Server->>Browser: HTTP Response
Servlet Request-Response Flow
HttpServletRequest
The HttpServletRequest
object encapsulates all the information sent by the client with the request. This includes:
- Request parameters: Data submitted via HTML forms (e.g.,
request.getParameter("username")
). - HTTP headers: Information like
User-Agent
,Accept
,Cookie
(e.g.,request.getHeader("User-Agent")
). - Session information: Access to the
HttpSession
object (e.g.,request.getSession()
). - Request URL and URI: The path and context of the request.
- Input stream: For reading raw request body data (e.g., for file uploads).
HttpServletResponse
The HttpServletResponse
object allows the servlet to construct and send the response back to the client. Key functionalities include:
- Setting HTTP status codes: Indicating success (200 OK), redirects (302 Found), errors (404 Not Found, 500 Internal Server Error) (e.g.,
response.setStatus(HttpServletResponse.SC_OK)
). - Setting HTTP headers: Adding custom headers or modifying standard ones (e.g.,
response.setHeader("Cache-Control", "no-cache")
). - Setting content type: Specifying the type of content being sent (e.g.,
response.setContentType("text/html")
). - Output stream/writer: For writing the actual response body (HTML, JSON, XML, etc.) back to the client (e.g.,
response.getWriter().println("<h1>Hello!</h1>")
).
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Set response content type
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
// Get a writer to send response back to client
PrintWriter out = response.getWriter();
// Get parameter from request
String userName = request.getParameter("name");
if (userName == null || userName.isEmpty()) {
userName = "Guest";
}
// Write HTML content to the response
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head><title>Hello Servlet</title></head>");
out.println("<body>");
out.println("<h1>Hello, " + userName + "!</h1>");
out.println("<p>This is a simple servlet example.</p>");
out.println("</body>");
out.println("</html>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// For simplicity, just call doGet for POST requests in this example
doGet(request, response);
}
}
Servlet Container's Role
The servlet container is the environment in which servlets run. It's a crucial component that manages the entire servlet lifecycle and provides essential services. Without a servlet container, servlets cannot function. Popular servlet containers include Apache Tomcat, Jetty, and WildFly (which also acts as a full Java EE application server).
The container performs several vital functions:
- Lifecycle Management: As discussed, it handles the instantiation, initialization, servicing, and destruction of servlets.
- Request Dispatching: It receives requests from the web server and dispatches them to the correct servlet based on URL mapping.
- Concurrency Management: It manages multiple threads to handle concurrent requests to the same servlet instance, ensuring efficient resource utilization.
- Resource Management: It provides access to resources like JNDI (Java Naming and Directory Interface) for database connections and other services.
- Security: It enforces security constraints defined in the deployment descriptor (
web.xml
) or via annotations. - Session Management: It provides mechanisms for tracking user sessions across multiple requests.
- JSP Integration: It compiles and executes JavaServer Pages (JSPs), which are often used in conjunction with servlets to separate presentation logic from business logic.