1. What is a Servlet?
A Servlet is a Java class that runs on a web server. Its job is simple: receive an HTTP request from a browser, process it, and send back an HTTP response.
Think of it like this: when you fill out a login form on a website and click "Submit," that request goes to a Servlet on the server. The Servlet checks your credentials, talks to a database if needed, and sends back either a "Welcome" page or an "Invalid login" page.
It runs inside a Servlet Container (like Apache Tomcat), which manages the Servlet's lifecycle.
How a Request Flows
Client (Browser) | | HTTP Request (GET /login) v Web Server (Tomcat) | v Servlet Container ← manages servlet lifecycle | v Your Servlet ← your Java code runs here | | HTTP Response (HTML page) v Client (Browser) ← sees the result
CGI vs Servlet
Before Servlets, websites used CGI (Common Gateway Interface) — a separate process for every request. Servlets replaced CGI because they are faster and more efficient.
| Feature | CGI | Servlet |
|---|---|---|
| Process per request | New process each time (heavy) | New thread each time (lightweight) |
| Language | Any (Perl, C, etc.) | Java only |
| Performance | Slow — process creation overhead | Fast — thread reuse, stays in memory |
| Portability | Platform-dependent | Platform-independent (Java) |
| Memory | High — each process has own memory | Low — threads share memory |
2. Servlet Lifecycle (ALWAYS ASKED)
The Servlet Container (Tomcat) manages every Servlet through three methods. You do not call these methods — the container calls them automatically.
The Three Lifecycle Methods
// 1. init() — Called ONCE when the servlet is first loaded public void init() { // Setup code: open DB connections, read config, etc. } // 2. service() — Called for EVERY request public void service(HttpServletRequest req, HttpServletResponse res) { // Dispatches to doGet() or doPost() based on request type } // 3. destroy() — Called ONCE when the servlet is being removed public void destroy() { // Cleanup: close DB connections, release resources }
Lifecycle Flow
Servlet Class loaded into memory | v init() ← called ONCE (servlet is born) | v service() ← called for EVERY request | | v v doGet() doPost() ← your code handles the request | v destroy() ← called ONCE (servlet is dying) | v Servlet is garbage collected
init()— called once when servlet is first loadedservice()— called for every request (you usually don't override this directly)destroy()— called once before servlet is removed from memory
init() is called for every request. It is NOT. init() runs only once. Only service() runs for every request.
3. Servlet API
Servlets use classes and interfaces from two packages. You need to know which classes come from which package.
javax.servlet (Generic)
| Class/Interface | What It Does |
|---|---|
Servlet | Base interface — defines init(), service(), destroy() |
GenericServlet | Abstract class that implements Servlet. Protocol-independent. |
ServletRequest | Generic request object |
ServletResponse | Generic response object |
ServletConfig | Config info for one servlet (init-params) |
ServletContext | Shared info for the entire web application |
RequestDispatcher | For forwarding/including requests |
Filter | Intercepts requests before they reach the servlet |
javax.servlet.http (HTTP-specific)
| Class/Interface | What It Does |
|---|---|
HttpServlet | Abstract class you extend to create HTTP servlets |
HttpServletRequest | HTTP request — has getParameter(), getSession(), etc. |
HttpServletResponse | HTTP response — has setContentType(), getWriter(), etc. |
HttpSession | Stores user session data across requests |
Cookie | Small data stored on the client browser |
HttpServlet (not GenericServlet). HttpServlet already handles HTTP-specific details for you.
Important HttpServletRequest Methods
| Method | Returns | Use |
|---|---|---|
getParameter("name") | String | Get form field value |
getAttribute("key") | Object | Get attribute set by another servlet |
getSession() | HttpSession | Get or create a session |
getRequestDispatcher("path") | RequestDispatcher | Get dispatcher for forward/include |
getMethod() | String | Returns "GET" or "POST" |
getCookies() | Cookie[] | Get all cookies sent by client |
getContextPath() | String | Returns the application's context path |
Important HttpServletResponse Methods
| Method | Use |
|---|---|
setContentType("text/html") | Tell browser the response is HTML |
getWriter() | Returns PrintWriter to write response body |
sendRedirect("url") | Redirect browser to a different URL |
addCookie(cookie) | Send a cookie to the client |
setStatus(code) | Set HTTP status code (200, 404, etc.) |
setHeader("name", "value") | Set a response header |
4. Creating a Servlet
Step-by-Step: Your First Servlet
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; // Step 1: Extend HttpServlet public class HelloServlet extends HttpServlet { // Step 2: Override doGet() to handle GET requests protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Step 3: Set the content type of the response response.setContentType("text/html"); // Step 4: Get a PrintWriter to write output PrintWriter out = response.getWriter(); // Step 5: Write HTML to the response out.println("<html><body>"); out.println("<h1>Hello from Servlet!</h1>"); out.println("</body></html>"); } }
Configuring with web.xml
The web.xml file tells the Servlet Container (Tomcat) which URL maps to which Servlet class.
<!-- web.xml — inside WEB-INF folder --> <web-app> <!-- Step 1: Register the servlet --> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.example.HelloServlet</servlet-class> </servlet> <!-- Step 2: Map a URL pattern to the servlet --> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
http://localhost:8080/myapp/hello:1. Tomcat reads web.xml
2. Finds url-pattern
/hello → mapped to servlet-name HelloServlet3. Finds servlet-class
com.example.HelloServlet4. Runs that class's
doGet() method5. Returns the HTML response to the browser
Annotation-Based Configuration (Modern Way)
Instead of writing web.xml, you can use the @WebServlet annotation directly on the class. This is simpler and preferred in newer projects.
import javax.servlet.annotation.WebServlet; // The annotation replaces the web.xml configuration @WebServlet("/hello") // URL pattern — same as url-pattern in web.xml public class HelloServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); response.getWriter().println("<h1>Hello!</h1>"); } }
5. doGet() vs doPost()
| Feature | doGet() / GET | doPost() / POST |
|---|---|---|
| Data location | Appended to URL as query string | Sent in request body (hidden) |
| Data size | Limited (~2048 chars) | Unlimited |
| Visibility | Visible in URL bar and browser history | Not visible in URL |
| Bookmarkable | Yes | No |
| Security | Less secure (data in URL) | More secure (data in body) |
| Caching | Can be cached by browser | Not cached |
| Idempotent | Yes (same request = same result) | No (can cause side effects) |
| Use case | Fetching data (search, view page) | Submitting data (login, signup, payment) |
http://example.com/search?query=java&page=1The data (
query=java and page=1) is visible right in the URL. Anyone can see it, bookmark it, share it.
// Handling a GET request — e.g., showing a search page protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String query = request.getParameter("query"); // reads from URL response.setContentType("text/html"); response.getWriter().println("You searched for: " + query); } // Handling a POST request — e.g., login form submission protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); // reads from body String password = request.getParameter("password"); // Validate and respond... }
6. Request and Response Objects
Every time a request comes in, the Servlet Container creates two objects and passes them to your doGet()/doPost() method:
- HttpServletRequest — contains everything the client sent (form data, headers, cookies, URL info)
- HttpServletResponse — you use this to send data back to the client
Reading Form Data
Suppose you have this HTML form:
<!-- HTML form that sends data to the servlet --> <form action="register" method="post"> Name: <input type="text" name="name"> Email: <input type="email" name="email"> Age: <input type="number" name="age"> <button type="submit">Register</button> </form>
Here's how the Servlet reads that data:
@WebServlet("/register") public class RegisterServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // getParameter() reads the value of the form field by its "name" attribute String name = request.getParameter("name"); // "name" matches name="name" String email = request.getParameter("email"); // "email" matches name="email" String age = request.getParameter("age"); // Always returns String! // If you need age as int, parse it int ageNum = Integer.parseInt(age); // Set response content type response.setContentType("text/html"); // Get the writer and send HTML back PrintWriter out = response.getWriter(); out.println("<h1>Welcome, " + name + "!</h1>"); out.println("<p>Email: " + email + "</p>"); out.println("<p>Age: " + ageNum + "</p>"); } }
getParameter() always returns a String, even for number inputs. You must use Integer.parseInt() or Double.parseDouble() to convert if you need a number.
Response = what the server sends BACK to the client (HTML page, redirect, cookies).
7. RequestDispatcher — forward() vs sendRedirect()
Two ways to move the user from one page/servlet to another. They look similar but behave very differently.
forward() — Server-side
// forward(): the server internally sends the request to another resource // The browser URL does NOT change RequestDispatcher rd = request.getRequestDispatcher("welcome.jsp"); rd.forward(request, response); // same request & response objects are passed
sendRedirect() — Client-side
// sendRedirect(): tells the browser to make a NEW request to a different URL // The browser URL DOES change response.sendRedirect("welcome.jsp"); // browser sends a brand new request
include() — Include another resource's output
// include(): adds another resource's output to the current response // Useful for including headers, footers, etc. RequestDispatcher rd = request.getRequestDispatcher("header.jsp"); rd.include(request, response); // output is added to current response
Comparison Table (HIGH PRIORITY for exam)
| Feature | forward() | sendRedirect() |
|---|---|---|
| Happens on | Server side | Client side (browser) |
| URL in browser | Does NOT change | Changes to new URL |
| Request object | Same request is passed | New request is created |
| Speed | Faster (no extra round trip) | Slower (browser → server → browser → server) |
| Data sharing | Request attributes are available | Request attributes are lost |
| Can go to | Same web application only | Any URL (even external sites) |
| HTTP status | No redirect status sent | 302 status sent to browser |
sendRedirect() — After login, redirect to dashboard. After logout, redirect to login page. Redirecting to an external website.
8. Session Management (IMPORTANT)
Why Do We Need Sessions?
HTTP is stateless. This means the server does not remember you between requests. Every request is treated as a brand new one. But in a real app (like a shopping cart), the server needs to remember who you are across multiple pages.
Session management solves this. There are four ways to track users:
Method 1: HttpSession (Most Common)
// CREATING/GETTING a session HttpSession session = request.getSession(); // creates new if none exists // STORING data in the session session.setAttribute("username", "Darshan"); // key-value pair session.setAttribute("role", "admin"); // READING data from the session (in another servlet/page) String user = (String) session.getAttribute("username"); // returns Object, must cast // REMOVING a specific attribute session.removeAttribute("role"); // DESTROYING the entire session (logout) session.invalidate(); // session is gone, user is logged out
JSESSIONID=abc123)2. Server sends this ID to the browser as a cookie
3. Every subsequent request: browser automatically sends the cookie back
4. Server reads the ID, finds the matching session, and knows who you are
Method 2: Cookies
// CREATING and sending a cookie to the browser Cookie cookie = new Cookie("username", "Darshan"); // name-value pair cookie.setMaxAge(60 * 60); // expires in 1 hour (seconds) response.addCookie(cookie); // sends it to the browser // READING cookies from the request Cookie[] cookies = request.getCookies(); // returns array of all cookies if (cookies != null) { for (Cookie c : cookies) { if (c.getName().equals("username")) { String user = c.getValue(); // "Darshan" } } } // DELETING a cookie — set maxAge to 0 Cookie deleteCookie = new Cookie("username", ""); deleteCookie.setMaxAge(0); // 0 = delete immediately response.addCookie(deleteCookie);
Method 3: URL Rewriting
When cookies are disabled, the session ID is added to the URL.
// URL rewriting — appends session ID to the URL String encodedURL = response.encodeURL("nextpage.jsp"); // Result: nextpage.jsp;jsessionid=abc123 out.println("<a href='" + encodedURL + "'>Next Page</a>");
Method 4: Hidden Form Fields
<!-- Hidden field carries data that the user cannot see --> <form action="nextServlet" method="post"> <input type="hidden" name="userId" value="12345"> <button type="submit">Continue</button> </form>
Comparison of All Four Methods
| Method | Stored On | Works Without Cookies? | Security | Use Case |
|---|---|---|---|---|
| HttpSession | Server | No (uses cookie for session ID) | Most secure | Login sessions, shopping carts |
| Cookies | Client (browser) | N/A (it IS cookies) | Less secure (can be tampered) | Remember me, preferences |
| URL Rewriting | URL | Yes | Least secure (visible in URL) | Fallback when cookies disabled |
| Hidden Form Fields | HTML form | Yes | Moderate | Multi-step forms |
9. Filters
A Filter intercepts requests before they reach the Servlet and responses after the Servlet processes them. Think of it as a security guard at the door.
Use Cases
- Logging every request (who accessed what, when)
- Authentication check (is the user logged in?)
- Input validation
- Response compression
- Setting character encoding
Filter Lifecycle
Same pattern as Servlet: init() → doFilter() → destroy()
import javax.servlet.*; import java.io.*; public class LoggingFilter implements Filter { // Called once when filter is loaded public void init(FilterConfig config) { System.out.println("Filter initialized"); } // Called for every matching request public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // Code here runs BEFORE the servlet System.out.println("Request received at: " + new java.util.Date()); // Pass the request to the next filter or servlet chain.doFilter(request, response); // THIS LINE IS CRITICAL // Code here runs AFTER the servlet has processed the request System.out.println("Response sent"); } // Called once when filter is destroyed public void destroy() { System.out.println("Filter destroyed"); } }
chain.doFilter(request, response), the request will NEVER reach the servlet. The user will see a blank page. Always call it unless you intentionally want to block the request (e.g., unauthorized user).
Configuring a Filter in web.xml
<filter> <filter-name>LoggingFilter</filter-name> <filter-class>com.example.LoggingFilter</filter-class> </filter> <filter-mapping> <filter-name>LoggingFilter</filter-name> <url-pattern>/*</url-pattern> <!-- applies to ALL URLs --> </filter-mapping>
10. Listeners
Listeners "listen" for events in the web application — like when the app starts, a session is created, or an attribute changes. You write code that runs automatically when these events happen.
Common Listeners
| Listener | Listens For | Methods |
|---|---|---|
ServletContextListener | App startup and shutdown | contextInitialized(), contextDestroyed() |
HttpSessionListener | Session created/destroyed | sessionCreated(), sessionDestroyed() |
ServletRequestListener | Request created/destroyed | requestInitialized(), requestDestroyed() |
HttpSessionAttributeListener | Session attribute added/removed/replaced | attributeAdded(), attributeRemoved(), attributeReplaced() |
import javax.servlet.*; import javax.servlet.annotation.WebListener; @WebListener // annotation-based registration public class AppStartListener implements ServletContextListener { // Runs when the web application STARTS public void contextInitialized(ServletContextEvent event) { System.out.println("Application started!"); // Good place to: load config, initialize DB connection pool, etc. } // Runs when the web application STOPS public void contextDestroyed(ServletContextEvent event) { System.out.println("Application stopped!"); // Good place to: close connections, cleanup resources } }
HttpSessionListener — track how many users are currently logged in by counting active sessions.
11. web.xml Configuration
The web.xml file is the deployment descriptor. It lives inside the WEB-INF folder and tells Tomcat how to configure your web application.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="4.0"> <!-- 1. SERVLET REGISTRATION --> <servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.example.MyServlet</servlet-class> <!-- Init parameters — specific to this servlet --> <init-param> <param-name>dbURL</param-name> <param-value>jdbc:mysql://localhost:3306/mydb</param-value> </init-param> </servlet> <!-- 2. URL MAPPING --> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/myservlet</url-pattern> </servlet-mapping> <!-- 3. CONTEXT PARAMETERS — shared across ALL servlets --> <context-param> <param-name>appName</param-name> <param-value>My Web App</param-value> </context-param> <!-- 4. WELCOME FILE — default page when visiting root URL --> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 5. ERROR PAGE — custom error pages --> <error-page> <error-code>404</error-code> <location>/error404.html</location> </error-page> <error-page> <error-code>500</error-code> <location>/error500.html</location> </error-page> </web-app>
init-param vs context-param
| Feature | init-param | context-param |
|---|---|---|
| Scope | Specific to one servlet | Shared across entire application |
| Defined inside | <servlet> tag | Directly inside <web-app> tag |
| Access via | getServletConfig().getInitParameter("name") | getServletContext().getInitParameter("name") |
| Use case | DB URL for a specific servlet | App name, admin email — shared info |
getServletConfig().getInitParameter("paramName")"How do you read a context-param?" —
getServletContext().getInitParameter("paramName")Notice: both use
getInitParameter(), but one uses ServletConfig and the other uses ServletContext.
12. Servlet vs JSP
| Feature | Servlet | JSP |
|---|---|---|
| What it is | Java class with HTML inside Java code | HTML page with Java code inside |
| Good for | Processing logic (controllers) | Displaying output (views) |
| Modification | Requires recompilation | Auto-compiled by container |
| MVC role | Controller | View |
| Internally | Stays as a Servlet | Gets converted TO a Servlet by the container |
out.println() for every line of HTML.
// Servlet way — writing HTML inside Java (messy for large pages) out.println("<html><body>"); out.println("<h1>Hello, " + name + "</h1>"); out.println("</body></html>"); // JSP way — writing Java inside HTML (much cleaner for pages) // <html><body> // <h1>Hello, <%= name %></h1> // </body></html>
13. Practice Questions
request.getParameter("name") return?chain.doFilter() in a Filter?@WebServlet("/hello") maps the servlet to the /hello URL pattern. This replaces the servlet and servlet-mapping tags in web.xml.<welcome-file-list> in web.xml?init-param and context-param in web.xml?