Servlets are Java programs that run on a server, handling client requests and generating dynamic web content. They are a key part of Java’s server-side programming model.
1. What is a Servlet?
- Definition: A servlet is a Java class that handles HTTP requests and responses.
- Purpose:
- Process client requests (e.g., form submissions).
- Generate dynamic web content (e.g., HTML, JSON).
- Interact with databases or other server-side resources.
Example: Basic Servlet
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorldServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h1>Hello, World!</h1>");
}
}
2. Lifecycle of a Servlet
The servlet lifecycle consists of the following stages:
- Loading and Instantiation:
- The servlet class is loaded by the server and an instance is created.
- Initialization (
init()):- The
init()method is called once to initialize the servlet.
- The
- Request Handling (
service()):- The
service()method is called for each client request. - Delegates to
doGet(),doPost(), etc., based on the HTTP request type.
- The
- Destruction (
destroy()):- The
destroy()method is called when the servlet is taken out of service.
- The
Example: Lifecycle Methods
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class LifecycleServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("Servlet initialized");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
response.getWriter().println("<h1>Processing Request</h1>");
}
@Override
public void destroy() {
System.out.println("Servlet destroyed");
}
}
3. Sessions in Servlets
- Definition: A session represents a series of interactions between a client and a server over a period of time.
- Techniques to Manage Sessions:
- Cookies: Small pieces of data stored on the client.
- Hidden Fields: Data embedded in forms.
- URL Rewriting: Session ID is appended to the URL.
- HTTP Session API: Server-side session tracking using
HttpSession.
Example: Using HttpSession
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
HttpSession session = request.getSession();
session.setAttribute("user", "John Doe");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h1>Welcome, " + session.getAttribute("user") + "</h1>");
}
}
4. ServletConfig vs ServletContext
| Feature | ServletConfig | ServletContext |
|---|---|---|
| Scope | Specific to a single servlet. | Shared across the entire application. |
| Purpose | Used to pass initialization parameters to a servlet. | Provides global application-level configuration. |
| Access Method | getServletConfig() | getServletContext() |
Example:
@Override
public void init(ServletConfig config) {
String param = config.getInitParameter("configParam");
ServletContext context = config.getServletContext();
String globalParam = context.getInitParameter("globalParam");
}
5. RequestDispatcher
- Definition: The
RequestDispatcherinterface is used to forward a request to another resource (e.g., servlet, JSP). - Methods:
forward(request, response): Forwards the request to another resource.include(request, response): Includes the content of another resource in the response.
Example: Forwarding a Request
RequestDispatcher dispatcher = request.getRequestDispatcher("/anotherServlet");
dispatcher.forward(request, response);
Example: Including a Resource
RequestDispatcher dispatcher = request.getRequestDispatcher("/header.jsp");
dispatcher.include(request, response);
6. Cookies in Servlets
- Definition: Cookies are small pieces of data stored on the client-side to maintain state between requests.
- Methods in
javax.servlet.http.Cookie:setMaxAge(int expiry): Sets the expiry time in seconds.setValue(String value): Sets the cookie value.
Example: Setting a Cookie
Cookie cookie = new Cookie("user", "John Doe");
cookie.setMaxAge(3600); // 1 hour
response.addCookie(cookie);
Example: Reading a Cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("user".equals(cookie.getName())) {
System.out.println("User: " + cookie.getValue());
}
}
}
7. Asynchronous Servlets
- Definition: Introduced in Servlet 3.0, asynchronous servlets allow processing requests and responses asynchronously, freeing up server threads for other tasks.
Example: Asynchronous Servlet
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class AsyncServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
AsyncContext asyncContext = request.startAsync();
asyncContext.start(() -> {
try {
Thread.sleep(2000); // Simulating a long task
PrintWriter out = response.getWriter();
out.println("Asynchronous Response");
asyncContext.complete();
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
8. Filters in Servlets
- Definition: Filters preprocess or postprocess requests and responses. They can modify request/response headers, log information, or perform authentication checks.
Example: Logging Filter
import java.io.*;
import javax.servlet.*;
public class LoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
System.out.println("Filter initialized");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Request received at: " + System.currentTimeMillis());
chain.doFilter(request, response); // Pass request to next filter/servlet
}
@Override
public void destroy() {
System.out.println("Filter destroyed");
}
}
9. Event Listeners in Servlets
- Definition: Event listeners monitor lifecycle events of the servlet context, session, or request.
Example: Context Listener
import javax.servlet.*;
public class AppContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Application started");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Application stopped");
}
}
HTTP Methods in Servlets
HTTP methods define the type of request being made by the client to the server. The most commonly used methods are:
| HTTP Method | Description | Use Case |
|---|---|---|
| GET | Retrieves data from the server. | Fetching web pages or query results. |
| POST | Sends data to the server for processing. | Submitting forms or uploading files. |
| PUT | Replaces all current representations of the target resource with the uploaded content. | Updating an existing resource. |
| DELETE | Deletes the specified resource. | Deleting a user or resource from a database. |
| HEAD | Similar to GET, but only retrieves the headers, not the body. | Checking metadata like content type or size. |
| OPTIONS | Describes the communication options for the target resource. | Determining supported HTTP methods for a resource. |
| PATCH | Partially updates a resource. | Updating a field of a resource (e.g., modifying user data). |
| TRACE | Performs a message loop-back test along the path to the target resource. | Debugging requests or tracking routing paths. |
Differences Between HTTP Methods
| Feature | GET | POST | PUT | DELETE |
|---|---|---|---|---|
| Purpose | Retrieve data | Send data | Update/replace data | Delete data |
| Request Body | Not allowed | Allowed | Allowed | Not allowed |
| Idempotence | Yes | No | Yes | Yes |
| Caching | Supported | Not typically cached | Not cached | Not cached |
| Usage Example | Search queries | Form submissions | Update user profile | Delete user account |
Example: Handling HTTP Methods in a Servlet
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HttpMethodServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().println("GET method called");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().println("POST method called");
}
@Override
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().println("PUT method called");
}
@Override
protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().println("DELETE method called");
}
}
Testing the Servlet
Use tools like Postman or cURL to test different HTTP methods:
- GET:
curl -X GET http://localhost:8080/HttpMethodServlet - POST:
curl -X POST http://localhost:8080/HttpMethodServlet - PUT:
curl -X PUT http://localhost:8080/HttpMethodServlet - DELETE:
curl -X DELETE http://localhost:8080/HttpMethodServlet
Understanding HTTP methods and their appropriate usage is essential for building RESTful web applications and managing server-client interactions effectively.
How Spring Boot Uses Servlets in the Background
Spring Boot uses servlets in the background as a core part of its web layer for handling HTTP requests and responses. Here’s how it works:
Embedded Servlet Containers
Spring Boot integrates with embedded servlet containers like Tomcat, Jetty, or Undertow. These servlet containers serve as the runtime environment for servlets. When you run a Spring Boot application with web capabilities, it starts an embedded servlet container, eliminating the need for a separate server deployment.
Servlet Initialization
- Spring Boot Starter: When you include
spring-boot-starter-weborspring-boot-starter-tomcatdependencies, Spring Boot automatically configures the servlet environment. - Servlet Registration: Spring Boot registers and configures servlets via its auto-configuration mechanism. The primary servlet, called the DispatcherServlet, is automatically registered.
DispatcherServlet: The Core Servlet
- Purpose: The
DispatcherServletis a front controller that handles all incoming HTTP requests in a Spring MVC application. It delegates the requests to the appropriate controllers (via handler mappings) and processes the responses. - How It’s Registered: In a Spring Boot application,
DispatcherServletis automatically registered and mapped to the URL pattern/(to handle all requests). - Initialization: The servlet is initialized during the startup phase by the Spring Boot auto-configuration classes.
Custom Servlets
You can also manually register custom servlets if needed. For example:
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.http.HttpServlet;
@Configuration
public class CustomServletConfig {
@Bean
public ServletRegistrationBean<HttpServlet> customServlet() {
HttpServlet customServlet = new HttpServlet() {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.getWriter().write("Custom Servlet Response");
}
};
return new ServletRegistrationBean<>(customServlet, "/custom-servlet");
}
}
Servlet APIs in Spring Boot
Spring Boot abstracts the use of servlets, so you don’t typically interact with them directly. Instead, you use:
- Controllers: Annotated with
@RestControlleror@Controllerto handle HTTP requests. - Filters: To preprocess and post-process requests (via
javax.servlet.Filterororg.springframework.web.filter).
Behind the Scenes
- Servlet Context: Spring Boot sets up a
ServletContextduring initialization, which manages servlet lifecycle and mappings. - Servlet Mapping: The
DispatcherServletis registered as a single entry point, handling requests and delegating them to controllers or other components like filters or interceptors.
Default Embedded Server Lifecycle
- Spring Boot starts the application and initializes the embedded servlet container.
- The servlet container sets up the
ServletContext. - The
DispatcherServlet(and other servlets if any) are registered and mapped. - Incoming HTTP requests are routed through the servlet container to the
DispatcherServlet.
Why Servlet Is Important in Spring Boot
While developers interact mostly with higher-level abstractions like controllers and filters, the servlet remains critical for:
- Low-level HTTP request/response handling.
- Managing the lifecycle of web applications.
- Providing interoperability with the Java EE servlet API.
This layered architecture allows Spring Boot to offer a robust yet flexible web application framework.
Conclusion
Servlets form the backbone of Java’s server-side programming model. Understanding their lifecycle, session management techniques, filters, asynchronous processing, and event listeners is essential for building robust web applications.