Servlets: Overview, Architecture, and the Servlet Life Cycle
What is a Servlet?
A Servlet is a server-side Java class that extends the capabilities of a server by handling HTTP requests and generating dynamic responses. Servlets run inside a Servlet Container (e.g., Apache Tomcat, Jetty) that manages their lifecycle.
Servlet vs CGI
| Feature | Servlet | CGI |
|---|---|---|
| Process model | One instance, multiple threads | New process per request |
| Performance | Fast (thread reuse) | Slow (process creation overhead) |
| Platform | Java (portable) | Language-dependent (Perl, C, etc.) |
| State | Can maintain state across requests | Stateless by nature |
Servlet Architecture
A web application's requests flow: Browser → Web Server → Servlet Container → Servlet → Response. The container is responsible for loading the servlet class, creating its instance, and routing matching requests to it based on URL mappings defined in web.xml (or annotations).
The Servlet Interface
Every servlet, directly or indirectly, implements javax.servlet.Servlet:
| Method | Purpose |
|---|---|
init(ServletConfig config) | Called once when the servlet is loaded |
service(ServletRequest, ServletResponse) | Called for every request |
destroy() | Called once before the servlet is unloaded |
getServletConfig() | Returns configuration data |
getServletInfo() | Returns servlet metadata (author, version) |
In practice, most servlets extend the abstract class HttpServlet, which implements service() and delegates to doGet(), doPost(), etc. based on the HTTP method.
The Servlet Life Cycle
- Loading and Instantiation – The container loads the servlet class and creates a single instance (by default).
- Initialization (
init) – Called exactly once, before the servlet handles any request. Used for one-time setup (e.g., opening a DB connection pool). - Request Handling (
service) – Called once per request, on its own thread.HttpServlet.service()inspects the HTTP method and callsdoGet,doPost,doPut, ordoDeleteaccordingly. - Destruction (
destroy) – Called exactly once when the container shuts down or unloads the servlet, for cleanup.
A Minimal Servlet
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class HelloServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("HelloServlet initialized");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<h1>Hello from Servlet!</h1>");
}
@Override
public void destroy() {
System.out.println("HelloServlet destroyed");
}
}
Mapping a Servlet (web.xml)
<web-app>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
Or, using annotations (Servlet 3.0+)
@WebServlet("/hello")
public class HelloServlet extends HttpServlet { ... }
Key Takeaway: Servlets are managed by a container through a strict life cycle —init()once,service()(dispatching todoGet/doPost) on every request, anddestroy()once at shutdown. This thread-per-request model with a single loaded instance is what makes servlets far more efficient than CGI.