In our spring application, we use HttpServletRequest
in two ways:
(the code here are simplied, and seems meaningless)
In the controller:
@RequestMapping(value = "/hello", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> hello(HttpServletRequest request) {
System.out.println("## controller req.hashcode: " + request.hashCode());
System.out.println("## header 'abc': " + request.getHeader("abc"));
return new ResponseEntity<String>("OK", HttpStatus.OK);
}
In a normal component:
@Component
class RequestService {
private final HttpServletRequest request;
@Autowired
public RequestService(HttpServletRequest request) {
this.request = request;
}
public String getHeaderAbc() {
System.out.println("## service req.hashcode: " + request.hashCode());
return this.request.getHeader("abc");
}
}
At first, I was thinking the 2nd way is totally wrong, because it should only inject the request
instance once. So no matter when I invoke getHeaderAbc()
method, it should return the same value(of the first request).
But when I try it, I found several interesting things:
request.hashCode()
in controller is always different (as I expected)request.hashCode()
in RequestService
is always the same (as I thought)abc
!!!It seems for the singleton RequestService
, spring keeps the request
instance, but changed the headers it contains!
How to understand it?
Take a look at the scoped proxy. http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html Basically you inject a proxy that keeps a references to the current HttpRequest beans and gives you the right one, selecting it by the request id.
IMHO using HttpRequest outside of the web layer is not a good practice. I would use it only in the controlellrs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With