Servlets Explained: The Foundation of Java Web Apps
A servlet is a Java class that runs inside a web server (a "servlet container" such as Apache Tomcat or Jetty) and handles incoming HTTP requests by producing HTTP responses. In plain terms: a browser asks for a page, the servlet container hands that request to your servlet, your code runs, and you send back HTML, JSON, or any other content. Servlets are the bedrock layer that almost every Java web technology — JSP, Spring MVC, Spring Boot — is built on top of.
If you understand servlets, the rest of the Java backend world stops looking like magic.
How a servlet handles a request
When a request arrives, the container looks at the URL and decides which servlet should handle it. It then calls one of the servlet's methods based on the HTTP method:
doGet()for GET requests (reading a page)doPost()for POST requests (submitting a form)doPut(),doDelete()and others for the remaining HTTP methods
You override the method you need. The container passes in two objects: an HttpServletRequest (everything the client sent) and an HttpServletResponse (where you write your reply).
The servlet lifecycle
A servlet has a predictable life managed entirely by the container:
- Loading and instantiation — the container creates a single instance of your servlet class.
init()— called once, right after creation. Use it for one-time setup (database pools, config).service()— called for every request; it routes todoGet,doPost, etc. You usually do not overrideservice()directly.destroy()— called once before the servlet is removed, so you can release resources.
A key point that surprises beginners: the container creates one instance and serves many concurrent requests through it on different threads. So your servlet must be thread-safe — avoid mutable instance fields that change per request.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesYour first servlet
Modern servlets live in the jakarta.servlet package (the older javax.servlet namespace was renamed when Java EE moved to the Eclipse Foundation as Jakarta EE). Here is a complete, working example:
// Import the Jakarta Servlet API (NOT the old javax.* packages)
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
// @WebServlet maps this servlet to the URL "/greet" — no XML config needed
@WebServlet("/greet")
public class GreetServlet extends HttpServlet {
// Called automatically for GET requests to /greet
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// Read a query parameter, e.g. /greet?name=Asha
String name = request.getParameter("name");
if (name == null || name.isBlank()) {
name = "learner"; // safe default
}
// Tell the browser we are sending HTML in UTF-8
response.setContentType("text/html;charset=UTF-8");
// Write the response body
try (PrintWriter out = response.getWriter()) {
out.println("<h1>Hello, " + name + "!</h1>");
out.println("<p>This page was generated by a Java servlet.</p>");
}
}
}
Deploy this to Tomcat, visit http://localhost:8080/yourapp/greet?name=Asha, and the servlet builds the page on the fly.
Common mistakes
- Using
javax.servletinstead ofjakarta.servlet. Any current container (Tomcat 10+, Jetty 11+) expects thejakartanamespace. Mixing them causes "ClassNotFound" or unmapped-servlet errors. - Storing per-request data in instance fields. Because one instance serves many threads, a shared field like
private String currentUser;will leak data between users. Keep request-scoped data in local variables. - Forgetting to set the content type. Without
response.setContentType(...), browsers may guess wrong and render your HTML as plain text. - Doing heavy setup in
doGet. Database connections and config belong ininit(), which runs once, not on every request. - Not closing the writer/stream. Use try-with-resources, as shown above, so the response is flushed and resources are freed.
FAQ
Do I still need to learn servlets if I use Spring Boot? Spring Boot hides most servlet code, but it runs on a servlet container underneath. Knowing servlets helps you debug filters, sessions, and request handling when the abstraction leaks.
What is a servlet container? It is the runtime that manages servlet lifecycle and threading — Tomcat and Jetty are the most common. Spring Boot embeds one for you.
Is web.xml required?
No. The @WebServlet annotation replaces most XML configuration in modern apps.
Keep learning
Servlets are step one. Next, see how JSP builds views on top of servlets, how MVC architecture organises the whole app, and explore the full Advanced Java hub.
Ready to build real Java backends from the ground up? Join the waitlist for the Advanced Java course at Infoplanet, Jalgaon, and learn servlets, Spring Boot, and REST APIs with hands-on guidance.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesFounder, Infoplanet
Atul Kabra founded Infoplanet in 2001 and has spent over two decades teaching programming — C, C++, Java, databases and more — to students across Maharashtra.
Related guides
Advanced Java / Backend Roadmap
A clear, ordered roadmap for learning Advanced Java and backend development — from core Java through servlets, Spring Boot, REST APIs, and deployment.
Deploying a Java Web App
A practical guide to deploying a Spring Boot app: build an executable JAR, run it on a server, containerise with Docker, and check production essentials.
Hibernate & JPA Basics
Hibernate is the leading JPA implementation that maps Java objects to database tables. This guide explains ORM, entities, and the Jakarta Persistence annotations.
