简体   繁体   中英

How Spring MVC make HttpServletRequest field threadsafe?

Code:

package com.test.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/")
public class Controller {
    private HttpServletRequest request;

    public HttpServletRequest getRequest() {
        return request;
    }
    @Autowired
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }
    @RequestMapping("safe-read")
    public void threadSafeRead() throws InterruptedException {
        System.out.println(request.getHeader("user-agent"));
        Thread.sleep(TimeUnit.MILLISECONDS.convert(5,TimeUnit.SECONDS));
        System.out.println(request.getHeader("user-agent"));
    }
}

When I do two request in same time ,result of this execution is :

  1. Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
  2. Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36
  3. Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
  4. Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36

In runtime field have type com.sun.proxy.$Proxy45 . How spring make it thread-safe for read?

Just to expand a little on the comment by M. Deinum above, there are a few approaches you could use to avoid holding a reference to the request as part of the controller's state.

1) As already mentioned, directly inject the request as part of the method signature.

2) Only work with the request params that you are directly interested in by using the @RequestParam annotations in your method signatures.

3) Take a look at the Spring api doc for the RequestContextHolder class. You can do things like:

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

which may or may not be useful to you.

Hope this helps :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM