Jakarta Servlets Interview Questions and Answers
Master Jakarta Servlets with production-ready interview questions covering the Servlet lifecycle, HTTP methods, request and response handling, filters, listeners, sessions, cookies, dispatching, thread safety, async processing, and senior-level best practices.
Introduction
Jakarta Servlet is the foundational web specification for handling HTTP requests and responses in Jakarta EE applications.
Servlets provide the low-level web programming model used by many higher-level frameworks and specifications.
A Servlet can:
- Receive HTTP requests
- Read headers, parameters, cookies, and body content
- Execute application logic
- Set response status and headers
- Write HTML, JSON, files, or binary data
- Forward or include requests
- Manage sessions
- Start asynchronous processing
- Participate in filters and listeners
- Integrate with security and container services
Modern applications often use Jakarta REST, JSF, or frameworks built on top of the Servlet API. However, understanding Servlets remains important because the Servlet container controls:
- Request lifecycle
- Threading model
- Session lifecycle
- Filters
- Security integration
- Async dispatch
- Web application deployment
Servlets are widely discussed in Java web, Jakarta EE, Spring MVC, security, and backend interviews.
This guide covers the 15 most frequently asked Jakarta Servlet interview questions with code examples, Mermaid diagrams, production scenarios, common mistakes, and senior-level recommendations.
Q1. What is a Servlet?
Answer
A Servlet is a server-side Java component managed by a Servlet container to process client requests and generate responses.
Most Servlets extend HttpServlet.
Example
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/hello")
public class HelloServlet
extends HttpServlet {
@Override
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
response.setContentType(
"text/plain"
);
response
.getWriter()
.write(
"Hello from Jakarta Servlet"
);
}
}
Request Flow
flowchart TD
A[Browser] --> B[Servlet Container]
B --> C[URL Mapping]
C --> D[Servlet Instance]
D --> E[doGet or doPost]
E --> F[HTTP Response]
F --> A
Why Interviewers Ask This
Servlets are the foundation of Jakarta web applications and help explain how higher-level web frameworks operate.
Production Example
A Servlet may stream a large export file or act as a low-level callback endpoint.
Common Mistake
Describing a Servlet as a standalone web server.
Senior Follow-up
The Servlet is managed by a container that provides request dispatching, lifecycle, threading, security, session handling, and resource management.
Q2. Explain the Servlet lifecycle.
Answer
The Servlet container manages the complete Servlet lifecycle.
The main phases are:
- Class loading
- Instantiation
- Initialization
- Request processing
- Destruction
Lifecycle Methods
init()service()destroy()
Lifecycle Diagram
stateDiagram-v2
[*] --> ClassLoaded
ClassLoaded --> ServletCreated
ServletCreated --> Initialized: init()
Initialized --> Processing: service()
Processing --> Processing: More requests
Processing --> Destroyed: destroy()
Destroyed --> [*]
Lifecycle Flow
flowchart TD
A[Deploy Application] --> B[Load Servlet Class]
B --> C[Create Servlet Instance]
C --> D[Call init Once]
D --> E[Receive HTTP Requests]
E --> F[Call service for Each Request]
F --> E
E --> G[Application Shutdown or Redeploy]
G --> H[Call destroy Once]
Important Behavior
Typically:
- One Servlet instance handles many requests.
init()runs once.service()runs for every request.destroy()runs once before removal.
Common Mistake
Assuming a new Servlet instance is created for each request.
Senior Follow-up
Because one instance may handle concurrent requests, mutable instance fields create thread-safety risks.
Q3. What are init(), service(), and destroy()?
Answer
These methods define the Servlet lifecycle.
init()
Called once after the container creates the Servlet.
Use it for lightweight initialization.
@Override
public void init()
throws ServletException {
// Initialize configuration
}
service()
Called for each incoming request.
For HttpServlet, service() routes the request to methods such as:
doGet()doPost()doPut()doDelete()doHead()doOptions()
destroy()
Called once before the Servlet is removed.
@Override
public void destroy() {
// Release owned resources
}
Invocation Flow
sequenceDiagram
participant Container
participant Servlet
Container->>Servlet: Constructor
Container->>Servlet: init()
loop Every request
Container->>Servlet: service()
Servlet-->>Container: response
end
Container->>Servlet: destroy()
Best Practices
- Keep
init()fast. - Do not open unmanaged database connections and keep them forever.
- Use container-managed resources.
- Release only resources owned by the Servlet.
- Do not place per-request state in instance fields.
Common Mistake
Performing slow remote calls in init() and delaying application startup.
Senior Follow-up
Use dependency injection and container-managed services instead of building large custom lifecycle logic inside a Servlet.
Q4. What is the difference between doGet() and doPost()?
Answer
doGet() handles HTTP GET requests.
doPost() handles HTTP POST requests.
Comparison
| GET | POST |
|---|---|
| Retrieves data | Submits or creates data |
| Should be safe | May change server state |
| Should be idempotent | Not necessarily idempotent |
| Parameters often in URL | Data usually in request body |
| Can be cached | Usually not cached by default |
| Can be bookmarked | Usually not bookmarked |
| URL length limitations | Supports larger payloads |
GET Example
@Override
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
String customerId =
request.getParameter(
"customerId"
);
response
.getWriter()
.write(
"Customer: "
+ customerId
);
}
POST Example
@Override
protected void doPost(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
String name =
request.getParameter("name");
response.setStatus(
HttpServletResponse.SC_CREATED
);
response
.getWriter()
.write(
"Created customer: "
+ name
);
}
HTTP Semantics
flowchart LR
A[GET] --> B[Read Resource]
C[POST] --> D[Create or Process Resource]
E[PUT] --> F[Replace Resource]
G[PATCH] --> H[Partially Update Resource]
I[DELETE] --> J[Remove Resource]
Common Mistake
Using GET for operations that modify data.
Senior Follow-up
HTTP method selection should preserve semantic safety, idempotency, caching behavior, and retry expectations.
Q5. Servlet vs JSP?
Answer
A Servlet is a Java class used for request processing and response generation.
JSP was historically used as a server-side view technology for generating HTML.
Comparison
| Servlet | JSP |
|---|---|
| Java class | Template-style page |
| Better for control flow | Better for presentation |
| Handles request logic | Renders HTML |
| Compiled by developer | Translated into Servlet |
| Harder to write large HTML | Easier to write markup |
| Controller-style role | View-style role |
Traditional MVC Flow
flowchart TD
A[Browser Request] --> B[Servlet Controller]
B --> C[Service Layer]
C --> D[Model Data]
D --> B
B --> E[JSP View]
E --> F[HTML Response]
Request Forward
request.setAttribute(
"customer",
customer
);
request
.getRequestDispatcher(
"/WEB-INF/views/customer.jsp"
)
.forward(
request,
response
);
Common Mistake
Embedding business logic directly inside JSP pages.
Senior Follow-up
Modern APIs frequently return JSON rather than JSP views, but the Servlet MVC model remains important for understanding framework architecture.
Q6. What is HttpServletRequest?
Answer
HttpServletRequest represents the incoming HTTP request.
It provides access to:
- HTTP method
- URL
- Headers
- Query parameters
- Form parameters
- Cookies
- Request body
- Session
- Request attributes
- Authentication information
- Locale
- Network information
Example
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
String method =
request.getMethod();
String userAgent =
request.getHeader(
"User-Agent"
);
String page =
request.getParameter(
"page"
);
HttpSession session =
request.getSession(false);
}
Request Data Sources
flowchart TD
A[HttpServletRequest] --> B[Path]
A --> C[Query Parameters]
A --> D[Headers]
A --> E[Cookies]
A --> F[Body]
A --> G[Session]
A --> H[Security Principal]
A --> I[Request Attributes]
Request Attributes
Attributes allow server-side components to share data during one request.
request.setAttribute(
"correlationId",
correlationId
);
Common Mistake
Confusing request parameters with request attributes.
Senior Follow-up
Parameters originate from the client request, while attributes are server-side values attached during processing.
Q7. What is HttpServletResponse?
Answer
HttpServletResponse represents the outgoing HTTP response.
It allows the Servlet to configure:
- Status code
- Headers
- Cookies
- Content type
- Character encoding
- Response body
- Redirects
- Errors
- File downloads
JSON Example
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
response.setStatus(
HttpServletResponse.SC_OK
);
response.setContentType(
"application/json"
);
response.setCharacterEncoding(
"UTF-8"
);
response
.getWriter()
.write(
"""
{
"status": "UP"
}
"""
);
}
Download Example
response.setContentType(
"text/csv"
);
response.setHeader(
"Content-Disposition",
"attachment; filename=\"customers.csv\""
);
Response Flow
flowchart TD
A[Servlet] --> B[Set Status]
B --> C[Set Headers]
C --> D[Set Content Type]
D --> E[Write Body]
E --> F[Container Commits Response]
F --> G[Client Receives Response]
Committed Response
After the response is committed, changing status or headers may no longer be possible.
Common Mistake
Writing part of the body and then attempting a redirect.
Senior Follow-up
Buffering and commit timing matter for exception handling and streaming responses.
Q8. What are Servlet filters?
Answer
Filters intercept requests and responses before or after a Servlet or resource processes them.
Common uses include:
- Authentication
- Authorization
- Logging
- Correlation IDs
- CORS
- Compression
- Request wrapping
- Response headers
- Metrics
- Input sanitization
Filter Example
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
@WebFilter("/*")
public class CorrelationIdFilter
implements Filter {
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain
) throws IOException,
ServletException {
HttpServletRequest httpRequest =
(HttpServletRequest) request;
HttpServletResponse httpResponse =
(HttpServletResponse) response;
String correlationId =
UUID.randomUUID()
.toString();
httpRequest.setAttribute(
"correlationId",
correlationId
);
httpResponse.setHeader(
"X-Correlation-ID",
correlationId
);
chain.doFilter(
request,
response
);
}
}
Filter Chain
sequenceDiagram
participant Client
participant Filter1
participant Filter2
participant Servlet
Client->>Filter1: Request
Filter1->>Filter2: chain.doFilter()
Filter2->>Servlet: chain.doFilter()
Servlet-->>Filter2: Response
Filter2-->>Filter1: Response
Filter1-->>Client: Final response
Important Rule
A filter must call:
chain.doFilter(
request,
response
);
unless it intentionally stops processing.
Common Mistake
Forgetting to call the filter chain and unintentionally blocking requests.
Senior Follow-up
Filter order is important because authentication, tracing, exception handling, and CORS may depend on execution sequence.
Q9. What are Servlet listeners?
Answer
Servlet listeners observe lifecycle events related to:
- Web application context
- HTTP sessions
- Requests
- Attributes
Common Listener Interfaces
| Listener | Purpose |
|---|---|
ServletContextListener |
Application startup and shutdown |
HttpSessionListener |
Session creation and destruction |
ServletRequestListener |
Request lifecycle |
ServletContextAttributeListener |
Context attribute changes |
HttpSessionAttributeListener |
Session attribute changes |
ServletRequestAttributeListener |
Request attribute changes |
Application Listener Example
@WebListener
public class ApplicationLifecycleListener
implements ServletContextListener {
@Override
public void contextInitialized(
ServletContextEvent event
) {
System.out.println(
"Application started"
);
}
@Override
public void contextDestroyed(
ServletContextEvent event
) {
System.out.println(
"Application stopped"
);
}
}
Listener Flow
flowchart TD
A[Application Starts] --> B[ServletContextListener]
C[Request Begins] --> D[ServletRequestListener]
E[Session Created] --> F[HttpSessionListener]
G[Session Destroyed] --> F
H[Application Stops] --> B
Common Mistake
Using listeners to implement large business workflows.
Senior Follow-up
Listeners are suitable for lifecycle and infrastructure concerns, but business operations should remain in services or message-driven components.
Q10. How is session management handled?
Answer
HTTP is stateless, so the server uses session mechanisms to associate multiple requests with one client.
The Servlet API provides HttpSession.
Create or Retrieve Session
HttpSession session =
request.getSession();
Retrieve Existing Session Only
HttpSession session =
request.getSession(false);
Store Session Attribute
session.setAttribute(
"cartId",
cartId
);
Invalidate Session
session.invalidate();
Session Flow
sequenceDiagram
participant Browser
participant Container
participant SessionStore
Browser->>Container: First request
Container->>SessionStore: Create session
SessionStore-->>Container: Session ID
Container-->>Browser: Set session cookie
Browser->>Container: Next request with session cookie
Container->>SessionStore: Lookup session
SessionStore-->>Container: Existing session
Session Risks
- Excessive memory usage
- Session fixation
- Session hijacking
- Cluster replication overhead
- Stale data
- Concurrent requests from same user
- Large serialized objects
Common Mistake
Storing large entity graphs or files in the HTTP session.
Senior Follow-up
Use sessions sparingly and keep important business state in durable backend storage.
Q11. Cookies vs HTTP sessions?
Answer
Cookies are small pieces of data stored by the browser.
HTTP sessions store state on the server and commonly use a cookie to carry the session identifier.
Comparison
| Cookies | HTTP Session |
|---|---|
| Stored on client | Stored on server or external session store |
| Sent with requests | Identified through session ID |
| Small size | Can hold larger server-side state |
| Can persist beyond browser session | Usually expires after inactivity |
| Visible to browser | Actual data remains server-side |
| Security flags required | Session ID security required |
Cookie Example
Cookie preference =
new Cookie(
"theme",
"dark"
);
preference.setHttpOnly(true);
preference.setSecure(true);
preference.setMaxAge(
60 * 60 * 24 * 30
);
response.addCookie(
preference
);
Session Cookie Flow
flowchart LR
A[Browser] -->|Session ID Cookie| B[Servlet Container]
B --> C[Server-Side Session Data]
Important Cookie Flags
HttpOnlySecureSameSite- Path
- Domain
- Expiration
Common Mistake
Storing sensitive information directly inside a plain-text cookie.
Senior Follow-up
Store only minimal client-side data and protect session identifiers against XSS, interception, fixation, and cross-site request attacks.
Q12. What is request dispatching?
Answer
Request dispatching allows one server-side resource to forward to or include another resource.
Forward
Transfers request processing to another resource.
RequestDispatcher dispatcher =
request.getRequestDispatcher(
"/WEB-INF/views/customer.jsp"
);
dispatcher.forward(
request,
response
);
Include
Includes output from another resource in the current response.
dispatcher.include(
request,
response
);
Forward vs Redirect
| Forward | Redirect |
|---|---|
| Server-side | Client-side |
| Same request | New request |
| URL usually unchanged | Browser URL changes |
| Request attributes preserved | Request attributes lost |
| No extra network round trip | Extra round trip |
| Usually same application | Can target external URL |
Forward Flow
sequenceDiagram
participant Browser
participant ServletA
participant ServletB
Browser->>ServletA: Request
ServletA->>ServletB: Forward same request
ServletB-->>Browser: Response
Redirect Flow
sequenceDiagram
participant Browser
participant Servlet
Browser->>Servlet: Request
Servlet-->>Browser: 302 Location
Browser->>Browser: Follow new URL
Browser->>Servlet: New request
Common Mistake
Using forward after the response has already been committed.
Senior Follow-up
Use the Post/Redirect/Get pattern after successful form submission to prevent duplicate resubmission.
Q13. Are Servlets thread-safe?
Answer
Servlet instances are not automatically thread-safe.
The container typically uses one Servlet instance to process many concurrent requests using multiple threads.
Unsafe Servlet
@WebServlet("/counter")
public class CounterServlet
extends HttpServlet {
private int counter;
@Override
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
counter++;
response
.getWriter()
.write(
String.valueOf(counter)
);
}
}
The increment is not atomic and requests can interfere.
Concurrency Flow
sequenceDiagram
participant Thread1
participant Servlet
participant Thread2
Thread1->>Servlet: Read counter = 10
Thread2->>Servlet: Read counter = 10
Thread1->>Servlet: Write counter = 11
Thread2->>Servlet: Write counter = 11
Note over Servlet: One increment lost
Safer Stateless Servlet
@Override
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
String customerId =
request.getParameter(
"customerId"
);
response
.getWriter()
.write(customerId);
}
Use:
- Local variables
- Immutable shared state
- Thread-safe collaborators
- Container-managed services
Common Mistake
Storing request, response, user, or session information in Servlet instance fields.
Senior Follow-up
The best Servlet design is usually stateless, with request-specific values stored in local variables or request scope.
Q14. What are common Servlet mistakes?
Answer
Common mistakes include:
- Storing request data in instance fields.
- Assuming one Servlet instance per request.
- Forgetting to call
chain.doFilter(). - Using GET for state-changing operations.
- Returning sensitive stack traces.
- Writing response content before setting status and headers.
- Mixing
getWriter()andgetOutputStream(). - Creating unmanaged database connections.
- Keeping sessions too large.
- Storing entities in sessions.
- Ignoring session fixation.
- Not setting character encoding.
- Trusting request parameters without validation.
- Failing to escape HTML output.
- Performing long blocking work on request threads.
- Creating unmanaged threads.
- Failing to close request-body streams when manually handled.
- Redirecting after response commit.
- Ignoring content type.
- Hardcoding authentication logic in multiple Servlets.
Unsafe Shared State
@WebServlet("/profile")
public class ProfileServlet
extends HttpServlet {
private String currentUser;
}
Safe Request State
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) {
String currentUser =
request.getRemoteUser();
}
Mistake Impact
flowchart TD
A[Mutable Servlet Field] --> B[Concurrent Requests]
B --> C[Race Condition]
C --> D[Wrong User Data]
D --> E[Security Incident]
Interview Tip
Strong candidates explain Servlet threading and lifecycle rather than only method names.
Q15. What are senior-level Servlet best practices?
Answer
Senior developers should keep Servlets thin, stateless, secure, and focused on HTTP concerns.
Best Practices
- Keep Servlets stateless.
- Store request data in local variables.
- Delegate business logic to services.
- Use filters for cross-cutting web concerns.
- Use listeners only for lifecycle concerns.
- Validate all input.
- Set correct content type and encoding.
- Use meaningful status codes.
- Avoid leaking stack traces.
- Protect cookies and sessions.
- Regenerate session IDs after authentication.
- Limit session size.
- Use container-managed resources.
- Avoid unmanaged threads.
- Use async processing only when appropriate.
- Stream large files instead of loading them fully.
- Apply timeouts and request-size limits.
- Add correlation IDs.
- Monitor request latency and thread-pool usage.
- Prefer Jakarta REST for resource-oriented APIs.
Servlet Design Flow
flowchart TD
A[HTTP Request] --> B[Filter Chain]
B --> C[Servlet]
C --> D[Validate Input]
D --> E[Call Application Service]
E --> F[Create Response Model]
F --> G[Set Status and Headers]
G --> H[Write Response]
H --> I[Monitoring]
Senior Follow-up
Servlets should remain protocol adapters. Business rules, transaction management, and persistence should live in dedicated application layers.
Servlet Mapping
Annotation Mapping
@WebServlet(
name = "CustomerServlet",
urlPatterns = {
"/customers",
"/customers/*"
},
loadOnStartup = 1
)
public class CustomerServlet
extends HttpServlet {
}
XML Mapping
<servlet>
<servlet-name>
CustomerServlet
</servlet-name>
<servlet-class>
com.codewithvenu.CustomerServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
CustomerServlet
</servlet-name>
<url-pattern>
/customers/*
</url-pattern>
</servlet-mapping>
Mapping Flow
flowchart LR
A[/customers/101] --> B[Servlet Container]
B --> C[URL Pattern Match]
C --> D[CustomerServlet]
Servlet Request Lifecycle
sequenceDiagram
participant Client
participant Connector
participant FilterChain
participant Servlet
participant Service
Client->>Connector: HTTP request
Connector->>FilterChain: Create request and response
FilterChain->>Servlet: Invoke service()
Servlet->>Service: Execute use case
Service-->>Servlet: Result
Servlet-->>FilterChain: Write response
FilterChain-->>Connector: Complete processing
Connector-->>Client: HTTP response
HTTP Method Dispatch
flowchart TD
A[HttpServlet service] --> B{HTTP Method}
B -->|GET| C[doGet]
B -->|POST| D[doPost]
B -->|PUT| E[doPut]
B -->|DELETE| F[doDelete]
B -->|HEAD| G[doHead]
B -->|OPTIONS| H[doOptions]
B -->|TRACE| I[doTrace]
Request Data Model
flowchart TD
A[HTTP Request] --> B[Method]
A --> C[URI]
A --> D[Query String]
A --> E[Headers]
A --> F[Cookies]
A --> G[Body]
A --> H[Session ID]
A --> I[Security Principal]
B --> J[HttpServletRequest]
C --> J
D --> J
E --> J
F --> J
G --> J
H --> J
I --> J
Response Data Model
flowchart TD
A[HttpServletResponse] --> B[Status Code]
A --> C[Headers]
A --> D[Cookies]
A --> E[Content Type]
A --> F[Character Encoding]
A --> G[Response Body]
Character Encoding
For form or body data, set encoding before reading parameters where needed.
request.setCharacterEncoding(
"UTF-8"
);
response.setCharacterEncoding(
"UTF-8"
);
response.setContentType(
"application/json"
);
Common Problem
Incorrect encoding can corrupt:
- International names
- Special symbols
- Non-English messages
- JSON payloads
Error Handling
Sending Error
response.sendError(
HttpServletResponse
.SC_BAD_REQUEST,
"Invalid customer ID"
);
Structured JSON Error
response.setStatus(
HttpServletResponse
.SC_BAD_REQUEST
);
response.setContentType(
"application/json"
);
response
.getWriter()
.write(
"""
{
"code": "INVALID_REQUEST",
"message": "Customer ID is required"
}
"""
);
Error Flow
flowchart TD
A[Request Processing] --> B{Exception?}
B -->|No| C[Return Success]
B -->|Yes| D[Map Exception]
D --> E[Set HTTP Status]
E --> F[Return Safe Error Body]
F --> G[Log Internal Details]
Post/Redirect/Get Pattern
sequenceDiagram
participant Browser
participant Servlet
participant Database
Browser->>Servlet: POST form
Servlet->>Database: Save data
Database-->>Servlet: Success
Servlet-->>Browser: 303 Redirect
Browser->>Servlet: GET result page
Servlet-->>Browser: Render response
Benefit
Refreshing the final page does not repeat the original POST.
Session Fixation Protection
After successful authentication, change the session ID.
request.changeSessionId();
Flow
flowchart TD
A[Unauthenticated Session ID] --> B[User Logs In]
B --> C[Regenerate Session ID]
C --> D[Authenticated Session]
Cookie Security Example
Cookie sessionPreference =
new Cookie(
"language",
"en"
);
sessionPreference.setHttpOnly(true);
sessionPreference.setSecure(true);
sessionPreference.setPath("/");
response.addCookie(
sessionPreference
);
SameSite handling may require response-header configuration depending on runtime support.
Servlet Filters by Concern
| Filter Type | Purpose |
|---|---|
| Authentication Filter | Verify identity |
| Authorization Filter | Check permission |
| CORS Filter | Cross-origin policy |
| Logging Filter | Request and response logs |
| Correlation Filter | Distributed tracing ID |
| Compression Filter | Compress response |
| Security Header Filter | Add CSP and related headers |
| Encoding Filter | Force UTF-8 |
| Rate-Limit Filter | Limit request frequency |
| Exception Filter | Convert failures to safe responses |
Filter Ordering
flowchart LR
A[Request] --> B[Correlation Filter]
B --> C[Security Header Filter]
C --> D[Authentication Filter]
D --> E[Authorization Filter]
E --> F[Servlet]
F --> G[Response]
Order affects behavior and must be defined intentionally.
Request Wrapper Example
A filter can wrap a request to customize behavior.
HttpServletRequestWrapper wrapper =
new HttpServletRequestWrapper(
httpRequest
) {
@Override
public String getHeader(
String name
) {
if (
"X-Tenant-ID"
.equalsIgnoreCase(name)
) {
return normalizedTenantId;
}
return super.getHeader(name);
}
};
Use wrappers carefully so they do not hide important security or protocol behavior.
Response Wrapper Use Cases
Response wrappers can support:
- Response caching
- Audit capture
- Compression
- Body transformation
- Metrics
- Security-header enforcement
Avoid buffering huge responses in memory.
Asynchronous Servlet Processing
Servlet async support allows the request thread to be released while work continues.
Enable Async
@WebServlet(
value = "/reports",
asyncSupported = true
)
public class ReportServlet
extends HttpServlet {
}
Example
@Override
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) {
AsyncContext asyncContext =
request.startAsync();
asyncContext.setTimeout(
30_000
);
asyncContext.start(
() -> {
try {
HttpServletResponse asyncResponse =
(HttpServletResponse)
asyncContext
.getResponse();
asyncResponse
.setContentType(
"text/plain"
);
asyncResponse
.getWriter()
.write(
"Report completed"
);
} catch (IOException exception) {
throw new RuntimeException(
exception
);
} finally {
asyncContext.complete();
}
}
);
}
Async Lifecycle
sequenceDiagram
participant Client
participant RequestThread
participant AsyncTask
participant Response
Client->>RequestThread: Request
RequestThread->>AsyncTask: startAsync()
RequestThread-->>RequestThread: Return thread to pool
AsyncTask->>AsyncTask: Perform work
AsyncTask->>Response: Write result
AsyncTask->>Response: complete()
Response-->>Client: Final response
Important Warning
Asynchronous processing does not automatically make blocking work efficient. It changes thread usage and requires correct timeout, error, and context handling.
Async Listener
asyncContext.addListener(
new AsyncListener() {
@Override
public void onComplete(
AsyncEvent event
) {
}
@Override
public void onTimeout(
AsyncEvent event
) {
}
@Override
public void onError(
AsyncEvent event
) {
}
@Override
public void onStartAsync(
AsyncEvent event
) {
}
}
);
Blocking vs Async Processing
| Synchronous Servlet | Async Servlet |
|---|---|
| Request thread held | Request thread can be released |
| Simpler flow | More lifecycle complexity |
| Suitable for fast work | Suitable for deferred response |
| Easier transaction context | Context propagation must be handled |
| Blocking remote call holds thread | Work can continue separately |
Async Servlet is not the same as a fully non-blocking reactive architecture.
File Upload Considerations
Servlet applications can handle multipart requests.
@MultipartConfig(
maxFileSize = 10 * 1024 * 1024,
maxRequestSize =
20 * 1024 * 1024
)
@WebServlet("/upload")
public class UploadServlet
extends HttpServlet {
}
Best Practices
- Enforce file size limits.
- Validate content type.
- Generate safe storage names.
- Never trust original file names.
- Scan files where required.
- Stream to storage.
- Prevent path traversal.
- Apply authentication and authorization.
Large File Download
try (
InputStream input =
fileService.openStream(fileId);
ServletOutputStream output =
response.getOutputStream()
) {
input.transferTo(output);
}
Avoid loading the complete file into a byte array for large downloads.
Session Concurrency
The same HTTP session may receive concurrent requests.
sequenceDiagram
participant Tab1
participant SessionBean
participant Tab2
Tab1->>SessionBean: Update cart
Tab2->>SessionBean: Update cart
Note over SessionBean: Concurrent access possible
Session-scoped mutable state may still require concurrency control.
Servlet Context
ServletContext represents the web application.
Common Uses
- Access initialization parameters
- Share immutable application metadata
- Retrieve resources
- Register components programmatically
- Log application events
ServletContext context =
getServletContext();
String applicationName =
context.getInitParameter(
"applicationName"
);
Warning
Mutable objects stored in ServletContext are shared across the application and must be thread-safe.
Request vs Session vs Context Scope
| Scope | Lifetime | Shared By |
|---|---|---|
| Request attribute | One request | Components in same request |
| Session attribute | User session | Requests using same session |
| ServletContext attribute | Application lifetime | All application requests |
Servlet Thread Model
flowchart TD
A[Incoming Requests] --> B[Container Thread Pool]
B --> C[Thread 1]
B --> D[Thread 2]
B --> E[Thread N]
C --> F[Same Servlet Instance]
D --> F
E --> F
This is why Servlet instance fields must be handled carefully.
Low-Level Servlet Architecture
flowchart TD
A[Client] --> B[HTTP Connector]
B --> C[Servlet Container]
C --> D[Filter Chain]
D --> E[Servlet Mapping]
E --> F[HttpServlet]
F --> G[Application Service]
G --> H[Database or External Service]
H --> G
G --> F
F --> D
D --> C
C --> B
B --> A
Servlet vs Jakarta REST
| Servlet | Jakarta REST |
|---|---|
| Low-level HTTP API | Resource-oriented REST API |
| Manual status and body handling | Annotation-driven HTTP mapping |
| Manual parameter extraction | Parameter injection |
| Useful for streaming and low-level control | Better for standard JSON APIs |
| Foundation of web container | Higher-level abstraction |
| More boilerplate | Cleaner REST design |
Production Monitoring
Monitor:
- Request count
- Response status distribution
- Request latency
- Active request threads
- Queue length
- Session count
- Session size
- Async timeout count
- Upload and download throughput
- Filter latency
- Error count
- Thread-pool saturation
Monitoring Flow
flowchart TD
A[Servlet Request] --> B[Metrics Filter]
B --> C[Servlet Processing]
C --> D[Record Status and Duration]
D --> E[Monitoring Platform]
E --> F[Dashboard and Alerts]
Senior Servlet Checklist
Stateless Servlet
│
▼
Validated Input
│
▼
Correct HTTP Method
│
▼
Thin Protocol Logic
│
▼
Service Delegation
│
▼
Safe Session Handling
│
▼
Correct Status and Headers
│
▼
Monitoring and Security
Interview Quick Revision
| Concept | Purpose |
|---|---|
| Servlet | Processes HTTP requests |
init() |
One-time initialization |
service() |
Dispatches each request |
destroy() |
Final cleanup |
doGet() |
Handles GET |
doPost() |
Handles POST |
| Request | Incoming HTTP data |
| Response | Outgoing HTTP data |
| Filter | Intercepts request and response |
| Listener | Observes lifecycle events |
| Session | Server-side user state |
| Cookie | Client-side HTTP state |
| Forward | Server-side dispatch |
| Redirect | Client-side new request |
| AsyncContext | Deferred Servlet response |
Key Takeaways
- Jakarta Servlet is the foundational HTTP request and response specification in Jakarta EE.
- The Servlet container manages class loading, initialization, request processing, concurrency, and destruction.
init()runs once,service()runs per request, anddestroy()runs before removal.HttpServlet.service()dispatches requests to methods such asdoGet(),doPost(),doPut(), anddoDelete().- GET should be safe and idempotent, while POST is commonly used for non-idempotent processing or resource creation.
HttpServletRequestexposes client request data, whileHttpServletResponseconfigures status, headers, cookies, and body content.- Filters are appropriate for cross-cutting web concerns such as authentication, logging, CORS, tracing, and security headers.
- Listeners observe application, request, session, and attribute lifecycle events.
- HTTP sessions maintain server-side state across requests but must remain small, secure, and concurrency-aware.
- Cookies store client-side data and require secure flags and careful content selection.
- Forwarding reuses the same request on the server, while redirecting creates a new client request.
- One Servlet instance commonly handles many concurrent requests, so mutable instance fields are dangerous.
- Servlets should remain stateless and use local variables for request-specific data.
- Asynchronous Servlet processing can release request threads but introduces additional lifecycle, timeout, and context complexity.
- Large uploads and downloads should be streamed and protected by size, type, and authorization controls.
- Important business logic should live in services rather than Servlets, filters, listeners, or JSP pages.
- Senior developers design Servlets as thin HTTP adapters with explicit security, observability, resource management, and thread-safety guarantees.