Managing Request-Scoped Data in Java Servlets
Request attributes provide temporary storage bound to a single HTTP request transaction. These attributes persist throughout the entire request processing pipeline, making them accessible to any servlet or JSP participating in the same request via RequestDispatcher.
Scope Boundaries
Data stored in HttpServletRequest remains valid exclusively within the current request thread. When utilizing RequestDispatcher.forward(), the same request object propagates to the target resource, carrying all attributes with it. Conversely, sendRedirect() terminates the current request and initiates a new client-server transaction, effectively destroying the original attribute container.
Lifecycle Phases
- Instantiation: The servlet container generates a fresh request scope upon receiving an HTTP request, immediately before invoking the service method.
- Active Phase: Attributes remain accessible throughout servlet processing, filter chains, and forwarded resources.
- Termination: The container invalidates the scope automatically after the response commits to the client.
Implementation Examples
Storing values before dispatching:
package com.example.servlet.scope;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/store-data")
public class DataInjectionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Map<String, Object> userProfile = new HashMap<>();
userProfile.put("roles", Arrays.asList("admin", "editor"));
userProfile.put("active", true);
request.setAttribute("profile", userProfile);
request.setAttribute("sessionToken", "tkn-8842-a");
request.setAttribute("sessionToken", "tkn-8842-b");
request.getRequestDispatcher("/retrieve-data").forward(request, response);
}
}
Accessing and cleaning up attributes:
package com.example.servlet.scope;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
@WebServlet("/retrieve-data")
public class DataExtractionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.removeAttribute("sessionToken");
Map<String, Object> profile = (Map<String, Object>) request.getAttribute("profile");
System.out.println("User roles: " + profile.get("roles"));
System.out.println("Token after removal: " + request.getAttribute("sessionToken"));
String clientId = request.getParameter("clientId");
System.out.println("Query parameter: " + clientId);
}
}