- Explain why Servlets replaced traditional CGI (Common Gateway Interface).
- Understand the role of the Web Container (e.g. Apache Tomcat).
- Master the process vs. thread execution model in high-concurrency web servers.
In the 1990s, when a user submitted a form on a website, the server ran a CGI script (written in Perl or C). For every single user click, the operating system had to fork a brand new, heavy OS process! If 1,000 students checked their BCA exam results simultaneously, the server spawned 1,000 OS processes, ran out of memory, and crashed!
Java Servlets solved this overnight: the web server runs one persistent JVM process, and each incoming HTTP request is assigned a lightweight Java thread from a pre-allocated thread pool. 1,000 requests = 1,000 threads, which requires only a few megabytes of RAM!
| Evaluation Parameter | CGI (Common Gateway Interface) | Java Servlets |
|---|---|---|
| Execution Model | Spawns a brand new, heavyweight operating system process for every client HTTP request. | Spawns a lightweight Java thread within the same shared JVM process. |
| Memory Overhead | Massive; 1,000 requests = 1,000 OS processes (server crashes under moderate traffic). | Minimal; 1,000 requests = 1,000 lightweight threads sharing a single servlet instance. |
| Performance & Speed | Very slow; process creation, initialization, and termination adds high latency. | Extremely fast; threads are drawn instantly from a pre-warmed thread pool. |
| Platform Portability | Platform dependent; compiled binaries (C/C++) must be recompiled for each target OS. | 100% platform independent; "Write Once, Run Anywhere" on any compliant servlet container (Apache Tomcat, Jetty, WildFly). |
| Security & Robustness | CGI scripts run directly against the OS shell, presenting severe security vulnerabilities. | Executes within the secure, sandboxed JVM with automatic Garbage Collection and type safety. |
Every Java servlet fundamentally implements the javax.servlet.Servlet interface, which forms the root of the servlet API hierarchy:
javax.servlet.Servlet Interface:
public void init(ServletConfig config) throws ServletException: Lifecycle method invoked once during servlet initialization.public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException: Lifecycle method called for every client request.public void destroy(): Lifecycle method called once when the servlet is unloaded or container shuts down.public ServletConfig getServletConfig(): Returns initialization parameters and configuration details for this servlet.public String getServletInfo(): Returns a string containing information about the servlet (author, version, copyright).
| Comparison Parameter | GenericServlet |
HttpServlet |
|---|---|---|
| Package | javax.servlet.GenericServlet |
javax.servlet.http.HttpServlet |
| Protocol Dependency | Protocol-independent; can handle any network protocol (HTTP, FTP, SMTP). | HTTP-specific; explicitly designed for the World Wide Web. |
| Abstract Methods | Only service() is abstract; subclasses must implement it. |
No abstract methods; provides default HTTP-405 implementations for doGet(), doPost(), etc. |
| Request/Response Types | Accepts generic ServletRequest and ServletResponse. |
Accepts HTTP-specific HttpServletRequest and HttpServletResponse (supporting headers, cookies, sessions). |
| Usage Frequency | Rarely used in practice. | Used in >99% of real-world web applications. |
The Three Lifecycle Stages in Detail:
- Stage 1: Initialization —
init(ServletConfig config): When the container receives the first request for the servlet (or on server startup if<load-on-startup>is configured), the container loads the.classfile, creates a single object instance using the default constructor, and callsinit(). This method executes strictly once. It is used to allocate expensive resources (database connection pools, configuration files). - Stage 2: Request Handling —
service(ServletRequest, ServletResponse): For every incoming client request, the web container spawns or allocates a worker thread from its thread pool and callsservice(). In anHttpServlet, theservice()method inspects the HTTP request method (GET, POST, PUT, DELETE) and dispatches execution to the corresponding handler method (doGet(),doPost(), etc.). This executes many times concurrently. - Stage 3: Destruction —
destroy(): When the web server is stopped, the application is undeployed, or the container reclaims memory, the container callsdestroy()strictly once. It gives the servlet an opportunity to flush log buffers, close database connections, and release threads before the object is garbage-collected.
| Evaluation Parameter | doGet() |
doPost() |
|---|---|---|
| Data Transmission | Appended directly to the URL string: search?query=java&page=2 |
Encapsulated inside the HTTP Request Payload Body (completely hidden from browser URL bar). |
| Data Capacity | Severely limited by browser URL length limits (typically ~2,048 characters). | Practically unlimited; ideal for large form submissions and multi-megabyte file uploads. |
| Security & Privacy | Insecure; sensitive parameters (passwords, credit card numbers) appear in URL history, browser cache & web server access logs. | Secure; parameters never exposed in browser address bar. |
| Idempotency & Caching | Idempotent; repeated execution produces same state; safe to bookmark and cache in browser history. | Non-idempotent; re-submitting triggers "Confirm form resubmission" warning (can cause duplicate payments). |
| HTML Form Default | Default method when method attribute is omitted: <form method="GET"> |
Requires explicit attribute: <form method="POST"> |
Both objects are used to pass configuration parameters to servlets without hardcoding values in Java code, but their scopes are fundamentally different:
| Dimension | ServletConfig |
ServletContext |
|---|---|---|
| Scope of Existence | One per Servlet instance. Private to the specific servlet it configures. | One per Web Application. Global object shared by all servlets and JSPs in the application. |
| Configuration in web.xml | Configured inside <servlet> using <init-param> tags. |
Configured directly inside <web-app> using <context-param> tags. |
| Retrieval Method | getServletConfig().getInitParameter("name") |
getServletContext().getInitParameter("name") |
| Typical Use Case | Specific servlet settings: admin email address, local file upload directory path. | Global settings: enterprise database connection URL, global site theme name. |
<web-app>
<!-- Global Application Parameter (ServletContext) -->
<context-param>
<param-name>dbURL</param-name>
<param-value>jdbc:mysql://localhost:3306/bca_db</param-value>
</context-param>
<!-- Servlet Definition & Private Parameter (ServletConfig) -->
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.exam.LoginServlet</servlet-class>
<init-param>
<param-name>maxAttempts</param-name>
<param-value>3</param-value>
</init-param>
</servlet>
</web-app>
When a servlet completes its processing, it often needs to transfer control to another servlet, JSP, or external URL:
| Evaluation Parameter | RequestDispatcher.forward() |
HttpServletResponse.sendRedirect() |
|---|---|---|
| Mechanism & Location | Server-side transfer; the container internally passes control to the target resource without browser involvement. | Client-side redirection; server sends an HTTP 302 response header instructing the browser to issue a brand new GET request. |
| Browser Address Bar | Does NOT change; the browser URL remains the original servlet URL. | Changes visibly to the new target URL address. |
| Request Scope Data | Preserved; the target resource receives the original request and response objects (including request attributes). |
Destroyed; because a new HTTP request is generated, all previous request attributes are completely lost! |
| Target Destination | Only works for resources located within the same web application. | Can redirect to any valid URL on the entire internet (e.g. https://google.com). |
| Speed & Efficiency | Faster; only one round-trip between client and server. | Slower; requires two complete network round-trips (original request $\to$ 302 response $\to$ new request $\to$ response). |
| Java Syntax | RequestDispatcher rd = req.getRequestDispatcher("welcome.jsp"); |
res.sendRedirect("welcome.jsp"); |
Why is Session Tracking Necessary?
HTTP is a fundamentally Stateless Protocol. Every request sent by a browser is treated as a completely independent, brand-new transaction. A web server does not inherently remember who you are when you move from page to page (e.g. remembering items in an e-commerce shopping cart). Session tracking bridges this gap by persisting client identity across multiple HTTP requests.
| Technique | Where Stored | How It Works | Key Limitations |
|---|---|---|---|
| 1. Cookies | Client Browser | Small text key-value pairs set by server via Set-Cookie response header and echoed back by browser in subsequent requests. |
Fails completely if user disables cookies in browser settings; security risk if sensitive data is stored. |
| 2. Hidden Form Fields | HTML Page Source | Hidden input tags: <input type="hidden" name="user_id" value="101"> carried between consecutive forms. |
Only works for consecutive form submissions; viewing page source exposes values; cannot track regular hyperlinks. |
| 3. URL Rewriting | Hyperlink URLs | Session identifier is dynamically appended to every hyperlink URL: page.jsp;jsessionid=A49DF82... |
All hyperlinks on every page must be dynamically encoded; session ID visible in address bar. |
| 4. HttpSession API | Server Memory | Server creates a unique session object in server RAM and sends back a unique JSESSIONID cookie to tie the browser to its server state. |
Industry Standard; consumes server memory for high concurrent traffic; scales with distributed caching. |
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class UserSessionServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
String username = req.getParameter("user");
// 1. Obtain or create server-side HTTP session
HttpSession session = req.getSession();
session.setAttribute("currentUser", username); // Bind object to session
session.setMaxInactiveInterval(30 * 60); // Session timeout: 30 minutes
// 2. Alternatively, create and attach a persistent Cookie
Cookie userCookie = new Cookie("userToken", username);
userCookie.setMaxAge(24 * 60 * 60); // 24 hours persistence
res.addCookie(userCookie);
out.println("<h2>Welcome, " + username + "!</h2>");
out.println("<p>Active Session ID: <code>" + session.getId() + "</code></p>");
out.println("<p>Creation Time: " + new java.util.Date(session.getCreationTime()) + "</p>");
out.println("<a href='#dashboard'>Go to Secure Dashboard</a>");
}
}
This is a standard 10-mark practical examination question requiring both the client HTML form and the backend Java Servlet:
<!DOCTYPE html>
<html>
<head>
<title>Square Calculator</title>
</head>
<body>
<h2>Calculate Square of a Number</h2>
<form action="SquareServlet" method="POST">
Enter a Number: <input type="number" name="num" required />
<input type="submit" value="Compute Square" />
</form>
</body>
</html>
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SquareServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
try {
// Read input parameter from HTTP request
String numStr = req.getParameter("num");
double n = Double.parseDouble(numStr);
double square = n * n;
// Generate dynamic HTML response
out.println("<!DOCTYPE html><html><head><title>Result</title></head><body>");
out.println("<h2>Calculation Result</h2>");
out.println("<p>Original Number: <b>" + n + "</b></p>");
out.println("<p>Square: <b>" + square + "</b></p>");
out.println("<a href='#square'>Calculate Another</a>");
out.println("</body></html>");
} catch (NumberFormatException e) {
out.println("<h3 style='color:red;'>Error: Please enter a valid numerical value!</h3>");
}
}
}
- Lifecycle Diagram (3 Marks): Draw the three boxes: `init(ServletConfig)` $\to$ `service(request, response)` $\to$ `destroy()`. Clearly mark `init()` and `destroy()` as called once, and `service()` as called per request with thread allocation.
- Stateless Nature of HTTP (2 Marks): Explicitly explain that HTTP is stateless before introducing session tracking.
- 4 Session Techniques (4 Marks): Create a 4-row comparative table with Cookies, Hidden Form Fields, URL Rewriting, and `HttpSession`. Mention that URL Rewriting works when cookies are disabled.
- Code Snippet (1 Mark): Write 4 lines of `HttpSession` code (`req.getSession()`, `session.setAttribute()`, `session.getAttribute()`).
• Confusing forward() and sendRedirect(): Writing that `sendRedirect()` preserves request attributes loses 3 marks. `sendRedirect()` causes a new browser request; request attributes are destroyed!
• Claiming init() is called per request: `init()` is strictly called ONCE when the servlet instance is initialized, not per request!
Answer all 10 questions covering Servlet lifecycles, HTTP methods, and the four session tracking techniques.