Trace servlet lifecycle, request handling and deliberate session changes.
☕ Java web⚙️ Lifecycle👤 Sessions🧪 Lab + MCQs
01
🎯Learning Objectives
A servlet is a Java component managed by a servlet container.
You will connect its lifecycle to HTTP handlers, distinguish request-local work from shared instance state and use sessions deliberately.
The examples use modern Jakarta Servlet APIs; compile and run them only with a matched dependency and runtime.
The interactive lab models a study-preference endpoint and two browser clients.
It is synchronous JavaScript: no Java, container, HTTP request, cookie, authentication or real session timeout runs here.
⚙️
Lifecycle
Explain init, service and destroy for one instance.
📨
Handlers
Read input and choose an HTTPresponse.
🧵
Isolation
Separate request-local variables from shared fields.
👤
Sessions
Read, create, invalidate and expire state deliberately.
02
🧰A Container-Managed Component
The container loads a servlet, creates an instance, initializes it and supplies request/response objects when handling requests.
Your servlet is not a standalone main program and its source is not executed by the browser.
Static hosting does not become a servlet runtime when you upload a Java file.
HttpServlet builds on the general Servlet lifecycle and dispatches HTTP requests to handlers such as doGet and doPost.
Application code usually overrides those handlers instead of replacing the HTTP service dispatcher.
The snippets target the jakarta.servlet namespace.
Legacy javax.servlet applications require their matching API and container.
A JVM, compiler, API dependency and web runtime have distinct responsibilities; having a java command alone is insufficient.
Who performs the work
🪟Client
Sends an HTTPrequest.
🧰Container
Maps, initializes and dispatches.
☕Servlet
Produces the application outcome.
📤Response
Returns metadata and a body.
03
🗺️Mapping and Context Paths
A servlet mapping selects the component within a deployed web application.
If the application context is /learning and the mapping is /study, a browser may request /learning/study.
The mapping is not the source filename.
Annotations such as @WebServlet can declare a mapping.
Deployment descriptors can also configure components.
Follow one consistent configuration so duplicate or conflicting mappings do not hide the handler you expect.
The lab accepts only /study and /logout as application-relative paths.
An unknown path returns a simulated 404 before the modeled component runs.
Its small exact-path router is not a replacement for container matching rules.
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
@WebServlet("/study")
public class StudyServlet extends HttpServlet {
// Add doGet/doPost handlers inside this class.
}
This declaration is illustrative.
It requires a compatible runtime, build configuration and correctly packaged application.
No /study Java endpoint is deployed by this website lesson.
04
⚙️Initialization: Prepare One Instance
The container calls init before that servlet instance services requests.
Initialization can be triggered when the component is first needed or configured to occur during application startup.
It is not repeated for every request.
Use initialization for component-level setup that has an appropriate lifetime.
A configuration or service reference is different from the current request’s learner name.
Do not initialize request-specific fields and then reuse them for later callers.
If initialization fails, the component cannot be treated as successfully ready.
Production behavior and diagnostics belong to the real runtime; the local lab demonstrates a successful initialization path only.
// Inside a servlet class; illustrative lifecycle hooks:
@Override
public void init() {
getServletContext().log("Study servlet initialized");
}
@Override
public void destroy() {
getServletContext().log("Study servlet destroyed");
// Release resources that this component actually owns.
}
The lab initializes lazily on its first mapped request, even when the HTTP method will later be rejected.
Unknown paths do not initialize the component.
Each modeled instance has its own generation number and service count.
05
📨Service and HTTP Handlers
After initialization, the container calls service with the request and response.
HttpServlet’s HTTP dispatcher selects an appropriate handler.
Override doGet to implement a read and doPost to implement an accepted submission.
A servlet instance can receive many requests.
The lifecycle has one initialization for that instance and repeated service calls.
A new instance after replacement has a new lifecycle; it is not a destroyed object being revived.
A complete HttpServlet has behavior for methods beyond the toy lab, including HEAD and OPTIONS.
The lab deliberately implements GET and POST on /study and POST on /logout; other methods return 405 with the appropriate Allow value.
Lifecycle of one instance
🌱Create
Container instantiates the component.
⚙️Initialize
Prepare before handling requests.
📨Service
Handle many requests.
🧹Destroy
Finish this instance’s lifecycle.
A mapped method rejection still reaches the simulated service dispatcher and increments its count.
The lab returns 503 for mapped requests after destruction until you create a new instance.
These counters explain its model, not container instrumentation.
06
🧹Destruction and Resource Ownership
The container invokes destroy as a lifecycle cleanup callback when removing a servlet from service.
Avoid assuming that a process crash will always permit normal cleanup.
Persistent data must not depend on a final callback successfully writing everything.
Release resources owned by the servlet according to their contract.
A container-managed data source, a request-scoped stream and a worker created by application code do not necessarily share the same ownership rules.
In a real container, servicing requests and lifecycle transitions have coordination rules.
The lab is synchronous and has no in-flight threads.
Its Destroy button stops future modeled service calls; it does not demonstrate concurrent shutdown safety.
🧹
Owned resources
Close what the component is responsible for.
🧵
In-flight work
Real concurrency needs separate verification.
🌱
Replacement
Create a new component instance.
📦
Session lifetime
A session and a servlet have different lifetimes.
The lab preserves its session map when replacing only the modeled servlet.
Real application redeployment may invalidate, preserve or restore sessions depending on configuration; do not rely on this toy replacement behavior as a deployment guarantee.
Reset clears the whole local demonstration.
07
🔎Request Parameters and Repeated Values
Request parameters arrive as strings and can have multiple values. getParameter returns one value; getParameterValues allows you to inspect multiplicity.
If your contract requires exactly one value, reject missing and repeated values rather than silently choosing one.
For POST /study, this lab accepts exactly learner and topic as scalar strings.
After trimming, learner must contain 2–40 Unicode code points with no control characters or unpaired surrogates.
Topic must be exactly html, servlets or jsp.
The simulated media type must be application/x-www-form-urlencoded.
Validation happens before a session is created or modified.
Invalid input returns 400; an unsupported media type returns 415.
The browserselector includes missing, repeated-value-shaped and extra-field requests to make these failures visible.
// Illustrative validation fragment inside doPost:
String[] values = request.getParameterValues("topic");
if (values == null || values.length != 1) {
response.sendError(400, "One topic is required");
return;
}
String topic = values[0];
if (!java.util.Set.of("html", "servlets", "jsp").contains(topic)) {
response.sendError(400, "Unknown topic");
return;
}
// Validate all remaining input before changing session state.
The Java fragment illustrates multiplicity and an allowlist; it is not the full browser validator ported into Java.
Define the actual Javarequest size, Unicode and media-type rules in your server implementation.
08
📤Response Status, Encoding and Commitment
Set the representation and character encoding before obtaining the writer or committing output.
Status and headers communicate the result; the body must match its declared representation.
A JSON body needs a proper serializer, not arbitrary string concatenation.
Once output is committed, changing headers, forwarding or sending an error may be too late.
Decide the outcome before writing a success body so validation failures do not produce half of one response and half of another.
The lab returns JSON-shaped local results for accepted reads, preference saves and logout.
It shows status, Content-Type, Allow when applicable and literal response source.
If you render user text into HTML, use the encoding appropriate to its destination.
JSON serialization and DOM textContent are different operations.
In this lab the browser preview uses text nodes and never interprets a learner label as HTML.
09
🧵Request-Local Variables and Shared Fields
One servlet instance may handle requests concurrently.
A mutable field named currentLearner can be overwritten by another request before the first response is finished.
Synchronizing all requests indiscriminately also risks unnecessary blocking and does not fix a poor state model.
Keep request input and computed response data in local variables or request attributes.
Shared dependencies must have a deliberate thread-safety strategy.
Do not assume a service, collection or counter is safe solely because a servlet owns it.
A session can also be accessed by multiple requests at once.
Concurrent browser tabs or parallel requests can race when reading and updating mutable attributes.
The synchronous lab verifies logical isolation between two clients, not real concurrency safety.
// Avoid: private String currentLearner;
// Prefer request-local data inside a handler:
String learner = request.getParameter("learner");
// Validate learner, then construct this request’s result locally.
📨
Local
One invocation’s input and result.
📄
Request attribute
Carry a model through a dispatch.
👤
Session
Deliberately associate state with a client session.
🌐
Shared dependency
Choose lifetime and concurrency controls.
10
👤Read a Session Without Creating One
request.getSession(false) returns the current valid session if one exists, or null when there is none.
The no-argument getSession() creates a session when necessary.
Choose deliberately: a read-only anonymous page should not accidentally allocate a session just to check for one.
A real container associates a session with client requests, commonly through a session cookie.
Session identifiers are not learner names and should not be designed as predictable authentication tokens.
URL rewriting exists but can expose identifiers in URLs and requires careful handling.
The lab uses obvious mock identifiers such as demo-1 and two in-memory client associations.
They are teaching labels, never browsercookies or secure identifiers.
An anonymous GET /study returns a clear empty state without creating a session.
// Illustrative read in doGet:
jakarta.servlet.http.HttpSession session = request.getSession(false);
Object preference = session == null ? null
: session.getAttribute("studyPreference");
// Render a controlled anonymous or accepted-preference result.
An existing session does not prove authentication or authorization.
This lesson saves fictional study preferences, not accounts, access rights or sensitive data.
11
💾Create and Update Session Attributes Deliberately
After all submission input has passed validation, a handler can obtain or create a session and set an accepted preference attribute.
Keep the stored value bounded and well-defined rather than copying the entire untrusted requestobject.
The lab stores only the validated learner label and allowed topic.
A later GET for that client reads a copied preference.
A second client starts anonymous until it makes its own accepted POST.
Saving client B does not overwrite client A.
Session attributes have application lifetimes and can outlive a request.
They are not a database durability guarantee.
Storage, replication, serialization and expiry behavior depend on the actual environment.
// Illustrative fragment AFTER complete input validation:
jakarta.servlet.http.HttpSession session = request.getSession();
session.setAttribute("studyPreference", acceptedPreference);
// acceptedPreference is a bounded application value prepared earlier.
Two client associations
🪟Client A
Mock association to session A.
👤Session A
A’s accepted study preference.
🪟Client B
Separate mock association.
👤Session B
B’s accepted study preference.
The lab updates a preference without creating a new session when the associated session is valid.
An invalid POST leaves the old preference and association unchanged.
12
🚪Invalidation, Expiry and Stale Associations
HttpSession.invalidate invalidates the session and unbinds its attributes.
Do not continue reading or modifying an invalidated sessionobject as if it were valid.
A later request may have no valid session even if the client still sends an old identifier.
Real inactivity expiry is controlled by container/session configuration. setMaxInactiveInterval uses seconds; non-positive values mean the session will not expire from that inactivity interval.
This is not a scheduled timer you should infer from the lab.
The Expire button manually deletes the selected client’s modeled serversession while leaving a stale mock association visible.
The next GET stays anonymous and creates nothing.
A valid POST creates a fresh modeled identifier.
// Illustrative logout handler logic:
jakarta.servlet.http.HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
// Return a deliberate logout outcome; do not create a new session.
POST /logout in the lab deletes the current valid session and clears that client’s association.
Repeating logout succeeds without creating a session.
It is a session-lifecycle demonstration, not a complete authentication/logout implementation.
13
🛡️Sessions Are Not a Complete Security System
Real authenticated applications need identity verification, authorization on protected operations and session fixation defenses.
Changing a session identifier after an authentication boundary is one relevant API capability; the application must still establish the identity correctly.
Cookie-authenticated state-changing requests need an appropriate CSRF defense.
Secure, HttpOnly and SameSite cookie settings address different risks and do not replace access-control checks or correct input/output handling.
Do not accept a submitted role or a predictable ID as proof of permission.
The browser model sends no cookies and authenticates nobody.
Its validation, literal rendering and client isolation checks are useful boundaries, but do not establish that a production servlet application is secure.
🔐
Identity
Verify who the caller is.
🛂
Authorization
Check the requested protected action.
🛡️
CSRF
Protect cookie-authenticated mutations.
📤
Output
Encode for the actual destination context.
Do not publish real credentials, session identifiers or sensitive learner records in teaching traces.
The lab uses fictional labels and public mock IDs only.
14
↪️Forward, Redirect and Post-Redirect-Get
A forward transfers the same request internally before commitment; request attributes can carry an accepted model to a JSP.
A redirect causes a new client request, so those attributes are not automatically copied across.
After a successful form submission, a Post-Redirect-Get flow can redirect to a read page and avoid repeating the same POST on an ordinary refresh.
It does not prevent all duplicate submissions or replace transaction/idempotency rules.
The local lab intentionally displays a direct JSON-shaped POST outcome so every decision remains visible.
It does not perform a redirect or claim to implement PRG.
// Illustrative MVC flow before response commitment:
request.setAttribute("study", acceptedModel);
request.getRequestDispatcher("/WEB-INF/views/study.jsp")
.forward(request, response);
// A different response choice for an accepted POST:
// Redirect to a server-controlled, context-aware read URL.
// Do not forward and redirect the same response.
Level 24 develops JSP views and their integration with a controller.
Keep view rendering separate from request validation and session changes.
15
🧪Separate Model Tests from Container Tests
A local model can test the order of routing, lifecycle gates, validation and session operations.
It can show that an invalid submission creates nothing, that logout is repeatable and that client B has no access to client A’s modeled preference.
A real project needs separate compilation and container checks: mappings, parameter multiplicity, encoding, cookies, actual expiry, response commitment, forwarding and concurrency.
A successful JavaScript simulation verifies none of those integrations.
Before using the lab, predict each outcome: GET anonymously, valid POST, repeated GET, client switch, malformed POST, expiry, logout, destruction and replacement.
Compare state before and after a rejected request.
⚙️
Lifecycle
Initialize once, service repeatedly, stop after destroy.
👤
Isolation
A and B keep separate accepted preferences.
📨
Rejections
Validation failures leave session state unchanged.
🧩
Integration
Verify the actual runtime independently.
The visualizer walks through one accepted POST.
The lab exposes every current modeled session for teaching; a real application must not provide an unrestricted session-inspection endpoint.
16
🔄Premium Visualizer — Servlet Lifecycle and Request
Trace one accepted study-preference POST through mapping, initialization, handler validation, session association and response. The approved five-stage player explains a local model; it does not run a Java servlet.
SERVLET LIFECYCLE AND REQUEST TRACE
Step 1 of 5
🗺️
STEP 01
Find the mapped servlet
The application-relative path selects the component.
POST /study
What is happening?
Unknown paths stop at routing. This player follows an accepted POST for one mock client.
17
🧪Premium Interactive — Servlet Lifecycle and Session Lab
Use client A or B to model separate browser associations.
GET /study reads without creating a session.
POST /study validates exactly learner and topic, then saves a preference.
POST /logout invalidates without creating.
Only the stated method/path contract is implemented.
Destroy stops the current modeled instance; create a new instance allows its next mapped request to initialize.
This component-only replacement preserves the mock session map.
Expire manually deletes a selected serversession but leaves a stale client association; it is not an inactivity timer.
Reset clears the entire model.
All identifiers and preferences are visible for teaching.
No Java, HTTP, cookies, authentication or persistent session storage is involved.
Completion is a separate local study marker.
Idle. Synchronous JavaScript model; no servlet container is running.
Servlet and session state · public teaching data
Current request trace
No request yet.
Response metadata and literal body
No response yet.
Safe text preview
No preview yet.
Lifecycle log · last 30 events
18
🛠️Debugging — Find the First Wrong Boundary
🗺️
Mapping
Check context path and annotation/descriptor mapping.
📨
Parameters
Inspect missing, repeated and invalid values before mutation.
👤
Sessions
Distinguish absent, valid and stale associations.
🧵
Shared fields
Look for request data stored on the servlet instance.
If every read creates a session, check whether the handler uses getSession() when it only needed getSession(false).
If a rejected POST still changes a preference, move all validation before session creation or attribute mutation.
If client B sees client A’s learner, inspect shared fields, static collections and association logic.
A request-local variable can prevent an accidental servlet-field leak, but real session concurrency still needs a deliberate strategy.
If headers fail to change, check whether response output was already committed.
If destroy appears to repeat, distinguish replacement instances and actual container callbacks from your own logging.
The lab is not a runtime debugger.
19
💬Interview Questions — Flip to Explain
QUESTION
Who calls init, service and destroy?
Click or press Enter to explain
ANSWER
The servlet container manages the lifecycle and invokes those callbacks.
QUESTION
Does init run for every request?
Click or press Enter to explain
ANSWER
No. It initializes that instance before servicing; a replacement instance has its own lifecycle.
QUESTION
Why override doGet or doPost instead of service in ordinary HTTP handlers?
Click or press Enter to explain
ANSWER
HttpServlet already dispatches HTTP methods; handlers express the application behavior without replacing that dispatcher.
QUESTION
Why avoid a mutable currentLearner instance field?
Click or press Enter to explain
ANSWER
One servlet instance can handle concurrent requests, so one caller can overwrite another’s data.
QUESTION
What is getSession(false) useful for?
Click or press Enter to explain
ANSWER
Reading an existing valid session without allocating a new session when there is none.
QUESTION
Does an existing session prove authentication?
Click or press Enter to explain
ANSWER
No. Identity and authorization require separate trustworthy application checks.
QUESTION
What happens after invalidation?
Click or press Enter to explain
ANSWER
The session is no longer valid; later requests may have no current session, and the old object must not be reused as valid.
QUESTION
Does this local lab verify actual cookie or container behavior?
Click or press Enter to explain
ANSWER
No. It checks a synchronous JavaScript model; real deployment, expiry and concurrency require integration tests.
20
❓MCQ Practice — Explain Servlet Decisions
PRACTICE
1. Who creates request and response objects for a servlet?
PRACTICE
2. When does init run for an instance?
PRACTICE
3. Which is a normal read handler?
PRACTICE
4. Where should one request’s learner input normally be kept?
PRACTICE
5. Which session call avoids creating a session?
PRACTICE
6. When does an invalid POST create a session in this lab?
PRACTICE
7. Which outcome is used for an unsupported mapped method?
PRACTICE
8. What happens to a destroyed modeled instance?
PRACTICE
9. Does an anonymous GET /study allocate a session?
PRACTICE
10. What does the Expire button demonstrate?
PRACTICE
11. Which value proves authorization by itself?
PRACTICE
12. Do synchronous model tests prove real servlet concurrency safety?
21
💻Extra Practice — Predict State Transitions
📭
Anonymous read
GET /study for A. Expect init once, 200 anonymous and zero sessions.
💾
Accepted save
POST /study, Demo learner/html. Expect one session, saved preference and another service call.
🪟
Other client
Switch to B and GET. Expect anonymous; A’s session remains unchanged.
📨
Rejected input
For A, POST a one-character label or repeated-value shape. Expect 400 and unchanged session data.
🚪
Logout twice
POST /logout twice for A. Expect 200 both times and no new session.
⌛
Stale association
Save, expire, then GET. Expect anonymous without recreation; valid POST then creates a new mock ID.
🧹
Destroy and replace
Destroy, then GET: 503 without a service call. Create a new instance and GET: init once for the new generation.
🛡️
Literal text
Save learner <Demo> and a valid topic. Expect literal text, JSON source and no injected element.
22
📌Quick Revision
🧰Container: Manages lifecycle and dispatch.
🗺️Mapping: Relative to the application context.
⚙️Init: Once for a successfully initialized instance.
A container-managed Java request-processing component.
TERM
HttpServlet
Click to see meaning
DEFINITION
HttpServlet
A servlet base class with HTTP method dispatch and handlers.
TERM
Context path
Click to see meaning
DEFINITION
Context path
The application’s path prefix within the server.
TERM
Servlet mapping
Click to see meaning
DEFINITION
Servlet mapping
A URL pattern associated with a component.
TERM
Initialization
Click to see meaning
DEFINITION
Initialization
Preparation before an instance services requests.
TERM
Response commitment
Click to see meaning
DEFINITION
Response commitment
The point at which response metadata/output has been sent and cannot be freely changed.
TERM
Request-local variable
Click to see meaning
DEFINITION
Request-local variable
A value local to one handler invocation.
TERM
HttpSession
Click to see meaning
DEFINITION
HttpSession
Container-managed state associated with a client session.
TERM
Invalidation
Click to see meaning
DEFINITION
Invalidation
Ending a session’s validity and unbinding its attributes.
TERM
Post-Redirect-Get
Click to see meaning
DEFINITION
Post-Redirect-Get
A flow that follows an accepted POST with a redirect to a GET resource.
24
🏆Final Challenge — Specify a Study Servlet
Specify GET /study as a read that does not create a session and POST /study as a validated preference save.
Define scalar parameter multiplicity, size/type rules, allowed topics and a stable representation before writing response output.
Add a logout operation that invalidates without creating, and explain how absent or expired sessions behave.
Keep request data local and identify which shared or session objects need concurrency controls in a real application.
Trace initialization, repeated service and destruction separately from session lifetime.
Design actual container tests for mapping, cookies, encoding, repeated parameters, expiry and lifecycle behavior.
The browser model is only one layer of verification.
Success criterion: explain the state before and after every accepted and rejected request, plus the integration checks that remain.
Level 24 continues with JSP — JavaServer Pages.
25
✅Level 23 Complete?
Explain lifecycle callbacks and HTTP dispatch, reproduce both mock clients’ independent preferences, and show that invalid input, logout and expiry do not accidentally create sessions. Identify the real-runtime checks this model cannot perform. Completion is a local study marker.