Spring MVC - 我可以在 RestController 中自动装配 HttpServletRequest

Lea*_*ner 1 scope spring-mvc httprequest

我可以HttpServletRequest在我的RestController类似下面自动装配吗,servletRequest即使它在高度并发的环境中执行,它也会返回不同的结果。我有一个限制,我不能作为方法参数,因为我正在实现一个自动生成的接口,不会HttpServletRequest作为方法参数。

@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){
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

我已经浏览了这些 SO 问题和其他一些关于此的文章。但只是想确保当我们HttpServletRequest在控制器中自动装配时,它的ScopeRequest

Spring 3 MVC 从控制器访问 HttpRequest

如何分配线程来处理 Servlet 请求?

Spring-Controller 的作用域及其实例变量

如何在 Spring bean 中获取 HttpServletRequest?

如何在 Java 中获取 HTTP 请求头


注意:我确实尝试过这个,它似乎工作正常。但只是想确认即使在高度并发的环境中它也是一个万无一失的解决方案。此外,如果这是正确的方法,如果有人能解释它的工作原理,我将不胜感激。

Kul*_*ain 8

我用过这个,效果很好。但不幸的是,我没有找到任何官方文档提到这应该有效。

以下是基于我通过运行具有不同标头/有效负载等的多个请求调试代码的理解的解释:

无论我们在字段上自动装配还是通过构造函数自动装配,servletRequest都像一个代理对象,它将调用委托给Current HttpServletRequest,每个请求都不同。因此,即使它是通过 Singleton RestController 中的构造函数注入的,对于每个新请求,它仍然会将调用委托给相应的 HttpServletRequest 。这利用AutowireUtils.ObjectFactoryDe​​legatingInvocationHandler来访问当前的 HttpServletRequest 对象。它的 java 文档还说Reflective InvocationHandler 用于延迟访问当前目标对象

因此,即使自动装配的 Proxy 对象对于所有请求总是相同的,调用被委派到的底层目标对象是每个请求的当前 HttpServletRequest 对象。


还有另一种方法,你可以得到HttpServletRequest使用RequestContextHolder中提到这个答案

HttpServletRequest currentRequest = 
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
Run Code Online (Sandbox Code Playgroud)

注意:由于此解释是基于我的理解,如果有人有任何官方文档,请分享有关此的任何官方文档。