How to Safely Access the HttpServletRequest in Spring MVC: 5 Proven Methods
This article explains various ways to obtain the HttpServletRequest object in a Spring MVC web application, evaluates their thread‑safety through concurrent testing, and compares the advantages and drawbacks of each approach to help developers choose the most efficient solution.
Overview
When developing Web systems with Spring MVC, the request object is frequently needed to retrieve client IP, URL, headers, cookies, authentication data, or request body content. Because Controllers, Services, and other Spring beans are singletons, it is crucial to ensure that each thread receives its own request instance.
The ways to obtain the request object can be divided into two categories: (1) usage inside Spring beans (Controller, Service, Repository, Component, etc.) and (2) usage outside beans (plain Java objects or static methods). The discussion also applies to response, InputStream/Reader, and OutputStream/Writer objects.
Testing Thread Safety
The basic idea is to simulate a large number of concurrent client requests and check whether the server uses the same request instance for different requests. Printing the request object's address is the most direct method, but thread pools can cause the same thread (and thus the same request instance) to handle multiple requests. To avoid this, the test sleeps the processing thread for a few seconds or distinguishes requests by unique attributes such as parameters, headers, or body content.
Client test code creates 1000 threads that each send a request (image omitted). The server-side Controller code (image omitted) prints the request object address. If the request is thread‑safe, the printed addresses differ; otherwise, identical addresses appear.
Method 1: Add HttpServletRequest as a Controller Parameter
Code Example
The simplest approach is to declare HttpServletRequest as a method parameter in the Controller. Spring injects the current request automatically.
After obtaining the request in the Controller, it can be passed to Service or utility methods as a parameter.
Thread Safety
Result: Thread‑safe – the request is a method‑local variable.
Pros & Cons
Requires adding the request parameter to every Controller method that needs it.
All downstream methods must also accept the request as a parameter, leading to code redundancy.
Method 2: Automatic Injection with @Autowired
Code Example
Spring injects a proxy for the request object into the bean. The actual request is retrieved from the proxy at runtime.
Thread Safety
Result: Thread‑safe – the proxy resolves to a thread‑local request instance.
Pros & Cons
Injection works in any bean (Controller, Service, Repository, etc.).
Can inject other request‑scoped objects such as HttpServletResponse or HttpSession.
Reduces code duplication compared with Method 1.
May still require repetitive injection statements if many Controllers need the request.
Method 3: Base Class Automatic Injection
Code Example
The injection code is moved to a common base class, and all Controllers extend this base class.
Thread Safety
Result: Thread‑safe – each derived Controller instance holds its own request reference.
Pros & Cons
Avoids repeated injection code in each Controller.
Limited by Java’s single‑inheritance rule; cannot be used if a Controller must extend another class.
Method 4: Manual Retrieval via RequestContextHolder
Code Example
Static utility code calls RequestContextHolder.currentRequestAttributes() to obtain the current request.
Thread Safety
Result: Thread‑safe – the underlying RequestAttributes are stored in a ThreadLocal.
Pros & Cons
Can be used in non‑bean classes.
Leads to verbose code if used frequently.
Method 5: @ModelAttribute Method
Code Example
A method annotated with @ModelAttribute runs before every @RequestMapping method, assigning the request to a field.
Thread Safety
Result: Not thread‑safe – the request is stored as a field in a singleton Controller, causing shared access across threads.
Conclusion
Methods 1‑4 (parameter injection, automatic @Autowired injection, base‑class injection, and manual retrieval) are all thread‑safe and suitable for obtaining the request object. For occasional use, any method works; for frequent use, automatic injection (Methods 2 and 3) is recommended to reduce redundancy. When the request is needed in non‑bean code, manual retrieval (Method 4) provides a viable solution.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
