Spring: how do I inject an HttpServletRequest into a request-scoped bean?
Asked Answered
O

3

128

I'm trying to set up a request-scoped bean in Spring.

I've successfully set it up so the bean is created once per request. Now, it needs to access the HttpServletRequest object.

Since the bean is created once per request, I figure the container can easily inject the request object in my bean. How can I do that ?

Olva answered 23/7, 2010 at 17:16 Comment(0)
D
152

Request-scoped beans can be autowired with the request object.

private @Autowired HttpServletRequest request;
Diclinous answered 24/7, 2010 at 7:27 Comment(8)
Is there an old fashioned XML way for this?Potboy
@cherouvim: I don't think so, no. The current request object is not visible as a bean reference.Diclinous
Doesn't work for me (spring mvc 3.1) - maybe there is something more that needs to be done? Going with Samit's solution.Marthena
The problem is that when you test validators using MockMvc and this kind of injection you'll have problems. May be the other solution will be preferred in this caseDday
It is possible to autowire HttpServletRequest also into non request-scoped beans, because for HttpServletRequest Spring will generate a proxy HttpServletRequest which is aware how to get the actual instance of request. So it is safe to autowire request even if your controller is singleton scoped.Subteen
Warning for Spring <=3.1 users the autowiring will not work running tests.Celin
Field request in xx.xx.xx.beans.i18n required a bean of type 'javax.servlet.http.HttpServletRequest' that could not be foundMastat
Note that this works in other (non-request-scoped) beans as well, but for wider-scoped beans, it's best to inject ObjectFactory<HttpServletRequest> and get the current request from that where needed.Ingram
A
165

Spring exposes the current HttpServletRequest object (as well as the current HttpSession object) through a wrapper object of type ServletRequestAttributes. This wrapper object is bound to ThreadLocal and is obtained by calling the static method RequestContextHolder.currentRequestAttributes().

ServletRequestAttributes provides the method getRequest() to get the current request, getSession() to get the current session and other methods to get the attributes stored in both the scopes. The following code, though a bit ugly, should get you the current request object anywhere in the application:

HttpServletRequest curRequest = 
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();

Note that the RequestContextHolder.currentRequestAttributes() method returns an interface and needs to be typecasted to ServletRequestAttributes that implements the interface.


Spring Javadoc: RequestContextHolder | ServletRequestAttributes

Aerodontia answered 24/7, 2010 at 1:0 Comment(3)
Injection is good resolution, but I have found problems with MockMvc testing Spring validators which inject HttpServletRequest. So if you want both mock tests and production code running properly this should be the choice.Dday
@Dday Why is it? for mock test(Unit test?), you can inject mock HttpServletRequest or whatever you want.. isn't it? Or you can use MockHttpServletRequest I guess?Funnyman
Is it safe to be used in a singleton-scoped service instance?Kelcie
D
152

Request-scoped beans can be autowired with the request object.

private @Autowired HttpServletRequest request;
Diclinous answered 24/7, 2010 at 7:27 Comment(8)
Is there an old fashioned XML way for this?Potboy
@cherouvim: I don't think so, no. The current request object is not visible as a bean reference.Diclinous
Doesn't work for me (spring mvc 3.1) - maybe there is something more that needs to be done? Going with Samit's solution.Marthena
The problem is that when you test validators using MockMvc and this kind of injection you'll have problems. May be the other solution will be preferred in this caseDday
It is possible to autowire HttpServletRequest also into non request-scoped beans, because for HttpServletRequest Spring will generate a proxy HttpServletRequest which is aware how to get the actual instance of request. So it is safe to autowire request even if your controller is singleton scoped.Subteen
Warning for Spring <=3.1 users the autowiring will not work running tests.Celin
Field request in xx.xx.xx.beans.i18n required a bean of type 'javax.servlet.http.HttpServletRequest' that could not be foundMastat
Note that this works in other (non-request-scoped) beans as well, but for wider-scoped beans, it's best to inject ObjectFactory<HttpServletRequest> and get the current request from that where needed.Ingram
S
8

As suggested here you can also inject the HttpServletRequest as a method param, e.g.:

public MyResponseObject myApiMethod(HttpServletRequest request, ...) {
    ...
}
Snivel answered 26/8, 2019 at 20:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.