Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't understand `@Autowired HttpServletRequest` of spring-mvc well

In our spring application, we use HttpServletRequest in two ways:

(the code here are simplied, and seems meaningless)

  1. 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);
    }
    
  2. 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:

  1. The request.hashCode() in controller is always different (as I expected)
  2. The request.hashCode() in RequestService is always the same (as I thought)
  3. But the header value is different if I issue a request with a different header abc !!!

It seems for the singleton RequestService, spring keeps the request instance, but changed the headers it contains!

How to understand it?

like image 420
Freewind Avatar asked Jan 19 '15 07:01

Freewind


1 Answers

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.

like image 92
Evgeni Dimitrov Avatar answered Sep 20 '22 11:09

Evgeni Dimitrov