Lecture 21: Servlet Architecture & Lifecycle

BMC201 - Web Technology

Mr. Prashant Kumar Nag

2026-03-16

Lecture 21

Servlet Architecture & Lifecycle

Week 8 | Unit III: JSP & Servlets Introduction
BMC201 - Web Technology
Mr. Prashant Kumar Nag, Assistant Professor

Learning Objectives


  • Understand what servlets are and their role
  • Explain servlet architecture components
  • Describe the servlet lifecycle phases
  • Write basic servlet classes
  • Configure servlets using web.xml and annotations

What is a Servlet?


Servlet is a Java program that runs on a web server to handle HTTP requests and generate dynamic responses.

Key Features:

  • Server-side technology
  • Platform-independent
  • Part of Java EE (Jakarta EE)
  • Extends HttpServlet class
  • Handles multiple requests concurrently

Why Use Servlets?


  • Dynamic Content: Generate HTML based on user input
  • Database Integration: Connect to databases for data operations
  • Session Management: Track user state across requests
  • Platform Independent: Write once, run anywhere
  • Powerful: Full access to Java APIs
  • Scalable: Handle multiple concurrent requests

Servlet Architecture


flowchart LR
    A[Client Browser] -->|HTTP Request| B[Web Server]
    B -->|Delegate| C[Servlet Container]
    C -->|Call| D[Servlet]
    D -->|Query| E[Database]
    E -->|Data| D
    D -->|Response| C
    C -->|HTTP Response| B
    B -->|Display| A

Architecture Components


1. Web Server

  • Receives HTTP requests (Apache Tomcat, Jetty)

2. Servlet Container (Servlet Engine)

  • Manages servlet lifecycle
  • Creates request/response objects

3. Servlet

  • Processes request and generates response

4. web.xml (Deployment Descriptor)

  • Maps URL patterns to servlets

Servlet Container Role


  • Load & Instantiate: Creates servlet instances
  • Initialize: Calls init() method
  • Request Handling: Calls service() method
  • Destroy: Calls destroy() when shutting down
  • Thread Management: Creates threads for concurrent requests
  • Security: Manages authentication & authorization

Servlet Lifecycle


stateDiagram-v2
    direction LR
    [*] --> Loading
    Loading --> Instantiation
    Instantiation --> Init: init()
    Init --> Service: doGet/doPost
    Service --> Service: Requests
    Service --> Destroy: destroy()
    Destroy --> [*]

Lifecycle Phases Explained


1. Loading & Instantiation

  • Container loads servlet class
  • Creates single servlet instance

2. Initialization (init())

  • Called once after instantiation
  • Initialize resources (database connections)

3. Request Handling (service())

  • Called for each client request
  • Delegates to doGet() or doPost()

Lifecycle Phases Explained (cont.)


4. Destruction (destroy())

  • Called once before servlet removal
  • Cleanup resources (close connections)

Key Points:

  • init() and destroy() called once
  • service() called multiple times (one per request)
  • Single servlet instance serves all requests (multithreaded)

Basic Servlet Structure


import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class HelloServlet extends HttpServlet {
  
  // Called once during initialization
  public void init() throws ServletException {
    System.out.println("Servlet initialized");
    // Initialize resources here
  }
  
  // Handle GET requests
  protected void doGet(HttpServletRequest request, 
                      HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<h1>Hello from Servlet!</h1>");
  }
  
  // Called once before destruction
  public void destroy() {
    System.out.println("Servlet destroyed");
    // Cleanup resources here
  }
}

HttpServlet Class Hierarchy


classDiagram
    direction LR
    class Servlet {
        <<interface>>
        +init()
        +service()
        +destroy()
    }
    
    class GenericServlet {
        <<abstract>>
        +init()
        +destroy()
        +service()
    }
    
    class HttpServlet {
        <<abstract>>
        +doGet()
        +doPost()
        +doPut()
        +doDelete()
    }
    
    class HelloServlet {
        +doGet()
        +doPost()
    }
    
    Servlet <|-- GenericServlet
    GenericServlet <|-- HttpServlet
    HttpServlet <|-- HelloServlet

service() Method Flow


// Container calls service() for every request
protected void service(HttpServletRequest request,
                      HttpServletResponse response) {
  String method = request.getMethod();
  if (method.equals("GET")) {
    doGet(request, response);
  } else if (method.equals("POST")) {
    doPost(request, response);
  }
  // ... and so on for PUT, DELETE, etc.
}

Usually, you override doGet() or doPost() instead of service().

Request & Response Objects


HttpServletRequest

  • Contains client request data
  • Methods: getParameter(), getHeader(), getSession()

HttpServletResponse

  • Sends response to client
  • Methods: setContentType(), getWriter(), sendRedirect()
// Get parameter from request
String name = request.getParameter("username");

// Set response type and send output
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<p>Welcome, " + name + "</p>");

Servlet with Initialization Parameters


public class ConfigServlet extends HttpServlet {
  private String adminEmail;
  
  public void init() throws ServletException {
    // Get init parameter from web.xml
    adminEmail = getServletConfig().getInitParameter("email");
  }
  
  protected void doGet(HttpServletRequest request,
                      HttpServletResponse response) 
    throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<p>Contact: " + adminEmail + "</p>");
  }
}

Servlet Configuration: web.xml


<!-- Define servlet -->
<servlet>
  <servlet-name>HelloServlet</servlet-name>
  <servlet-class>com.example.HelloServlet</servlet-class>
  
  <!-- Optional: init parameters -->
  <init-param>
    <param-name>email</param-name>
    <param-value>admin@example.com</param-value>
  </init-param>
  
  <!-- Optional: load on startup -->
  <load-on-startup>1</load-on-startup>
</servlet>

<!-- Map servlet to URL -->
<servlet-mapping>
  <servlet-name>HelloServlet</servlet-name>
  <url-pattern>/hello</url-pattern>
</servlet-mapping>

Servlet Configuration: Annotations


@WebServlet(
  name = "HelloServlet",
  urlPatterns = {"/hello", "/greet"},
  loadOnStartup = 1
)
public class HelloServlet extends HttpServlet {
  // ... servlet code
}

Annotations (Servlet 3.0+) eliminate need for web.xml configuration.

Commonly used: @WebServlet, @WebFilter, @WebListener

Annotation with Init Parameters


@WebServlet(
  urlPatterns = "/config",
  initParams = {
    @WebInitParam(name = "email", value = "admin@example.com"),
    @WebInitParam(name = "phone", value = "123-456-7890")
  },
  loadOnStartup = 1
)
public class ConfigServlet extends HttpServlet {
  public void init() {
    String email = getInitParameter("email");
    System.out.println("Email: " + email);
  }
}

URL Pattern Mapping


Exact Match

<url-pattern>/hello</url-pattern>

Matches: http://localhost:8080/app/hello

Path Match

<url-pattern>/admin/*</url-pattern>

Matches: http://localhost:8080/app/admin/users

Extension Match

<url-pattern>*.do</url-pattern>

Matches: http://localhost:8080/app/login.do

Load-on-Startup


Default Behavior: Servlet loaded on first request

load-on-startup: Load servlet when application starts

<load-on-startup>1</load-on-startup>
  • Positive number: Load order (1, 2, 3…)
  • Lower numbers loaded first
  • Use for servlets that initialize resources

Complete Servlet Example


@WebServlet(urlPatterns = "/welcome", loadOnStartup = 1)
public class WelcomeServlet extends HttpServlet {
  private int visitCount = 0;
  
  public void init() {
    System.out.println("WelcomeServlet initialized");
  }
  
  protected void doGet(HttpServletRequest request,
                      HttpServletResponse response)
    throws ServletException, IOException {
    visitCount++;
    
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html><body>");
    out.println("<h1>Welcome!</h1>");
    out.println("<p>Visit count: " + visitCount + "</p>");
    out.println("</body></html>");
    out.close();
  }
  
  public void destroy() {
    System.out.println("Total visits: " + visitCount);
    System.out.println("WelcomeServlet destroyed");
  }
}

Thread Safety Considerations


Problem: Single servlet instance serves multiple requests

  • Instance variables shared across requests
  • Multiple threads access same servlet object

Solution: Avoid instance variables for request-specific data

// BAD - instance variable
private String username; // Shared across all requests!

// GOOD - local variable
protected void doGet(...) {
  String username = request.getParameter("name"); // Thread-safe
}

Lifecycle Demonstration


@WebServlet("/lifecycle")
public class LifecycleServlet extends HttpServlet {
  
  public void init() {
    System.out.println("1. init() - Servlet initialized");
    System.out.println("   Thread: " + Thread.currentThread().getName());
  }
  
  protected void doGet(HttpServletRequest request,
                      HttpServletResponse response) 
    throws ServletException, IOException {
    System.out.println("2. doGet() - Handling request");
    System.out.println("   Thread: " + Thread.currentThread().getName());
  }
  
  public void destroy() {
    System.out.println("3. destroy() - Servlet destroyed");
    System.out.println("   Thread: " + Thread.currentThread().getName());
  }
}

Common Servlet Methods


Request Methods

request.getParameter("name")
request.getRequestURI()
request.getMethod()
request.getSession()
request.getHeader("User-Agent")

Response Methods

response.setContentType("text/html")
response.getWriter()
response.sendRedirect("login.html")
response.setStatus(200)

ServletConfig & ServletContext


ServletConfig

  • One per servlet
  • Access init parameters
  • getServletConfig().getInitParameter("param")

ServletContext

  • One per web application
  • Shared across all servlets
  • getServletContext().getAttribute("data")
ServletContext ctx = getServletContext();
ctx.setAttribute("appName", "MyApp");

Servlet Best Practices


  • Use annotations instead of web.xml (Servlet 3.0+)
  • Don’t store request-specific data in instance variables
  • Close resources in destroy() method
  • Set appropriate content type before writing response
  • Use PrintWriter.close() after writing output
  • Handle exceptions properly
  • Use thread-safe code practices

Common Mistakes to Avoid


  • Forgetting to extend HttpServlet
  • Not calling super.init() when overriding
  • Using instance variables for request data
  • Not setting content type
  • Forgetting servlet mapping in web.xml/annotation
  • Calling doGet() from doPost() without proper handling

Live Classroom Demo: Servlet Lifecycle


Use this interactive page during class to demonstrate:

  • Servlet lifecycle phases visualization
  • Init, service, and destroy method calls
  • Request counter simulation
  • Thread safety concepts
  • Configuration parameters

Alternative site path: /html/demos/lecture-21-demo.html

Summary


  • Servlets are Java programs running on web servers
  • Servlet container manages the lifecycle
  • Lifecycle: Load → Instantiate → Init → Service → Destroy
  • init() and destroy() called once
  • service() calls doGet() or doPost() per request
  • Configure using web.xml or annotations
  • Single servlet instance handles multiple requests (multithreaded)

Practice Exercise


Create a servlet that:

  1. Uses @WebServlet annotation with URL pattern /counter
  2. Maintains a visit counter in init() parameter
  3. Displays the current count in doGet()
  4. Prints lifecycle messages to console
  5. Logs total visits in destroy()

Bonus: Add initialization parameter for starting count value

Resources & References


Questions?

Next: Lecture 22 - HTTP GET & POST Requests