Reputation: 1523
Can I autowire HttpServletRequest
in my RestController
like following and will it returns different servletRequest
even if it is executed in highly concurrent environment. I have a restriction that I can not have as method parameter because I am implementing an interface which is auto generated and will not have HttpServletRequest
as the method parameter.
@RestController
public class MyController implements MyInterface {
@Autowired
private HttpServletRequest servletRequest;
@Override
@RequestMapping(value = "/test", produces = {"application/json"}, consumes = {"application/json"}, method = RequestMethod.POST)
public ResponseEntity<MyResponse> test(@RequestBody final MyRequest payload){
...
}
...
}
I have gone through these SO questions and some other articles on this. But just wanted to ensure that when we autowire HttpServletRequest
in the controller then its Scope is Request?
Spring 3 MVC accessing HttpRequest from controller
How are Threads allocated to handle Servlet request?
Scope of a Spring-Controller and its instance-variables
How do I get a HttpServletRequest in my spring beans?
How To Get HTTP Request Header In Java
Note: I did try this and it seems to work fine. But just wanted to confirm that it's a foolproof solution even in a highly concurrent environment. Also if this is the correct way to do it, I would appreciate if someone can explain how exactly it works.
Upvotes: 3
Views: 6176
Reputation: 8598
I have used this and it works fine. But unfortunately I did not find any official documentation which mentions that this should work.
Here is the explanation based on my understanding from debugging the code with running multiple requests with different headers/payload etc.:
Whether we autowire on field or through the constructor, servletRequest
acts like a Proxy object which delegates the call to Current HttpServletRequest which is different for each request. Thus, even though it's injected through constructor in a Singleton RestController, it will still have the call delegated to corresponding HttpServletRequest for each new request. This utilizes AutowireUtils.ObjectFactoryDelegatingInvocationHandler to access the current HttpServletRequest object. The java doc for it also says Reflective InvocationHandler for lazy access to the current target object.
Thus even if the autowired Proxy object is always the same for all requests, the underlying target object to which the call is delegated is the current HttpServletRequest object which is per-request.
There is another way you can get HttpServletRequest
is using RequestContextHolder
as mentioned in this answer
HttpServletRequest currentRequest =
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
Note: As this explanation is based on my understanding, please do share any official documentation about this if anyone has it.
Upvotes: 9