简体   繁体   English

Spring MVC如何使HttpServletRequest字段具有线程安全性?

[英]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 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 Mozilla / 5.0(Windows NT 6.1; WOW64)AppleWebKit / 537.36(KHTML,例如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 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 Mozilla / 5.0(Windows NT 6.1; WOW64)AppleWebKit / 537.36(KHTML,例如Gecko)Chrome / 32.0.1700.102 Safari / 537.36

In runtime field have type com.sun.proxy.$Proxy45 . 在运行时字段中,输入com.sun.proxy.$Proxy45 How spring make it thread-safe for read? spring如何使其具有线程安全性以供读取?

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. 只是为了扩展上面M. Deinum的评论,可以使用一些方法来避免将对请求的引用作为控制器状态的一部分保存。

1) As already mentioned, directly inject the request as part of the method signature. 1)如前所述,直接将请求作为方法签名的一部分。

2) Only work with the request params that you are directly interested in by using the @RequestParam annotations in your method signatures. 2)仅通过在方法签名中使用@RequestParam批注来处理您直接感兴趣的请求参数。

3) Take a look at the Spring api doc for the RequestContextHolder class. 3)看一下RequestContextHolder类的Spring api文档。 You can do things like: 您可以执行以下操作:

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

which may or may not be useful to you. 这可能对您没有用处。

Hope this helps :-) 希望这可以帮助 :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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