Spring:如何将 HttpServletRequest 注入到请求范围的 bean 中?
Posted
技术标签:
【中文标题】Spring:如何将 HttpServletRequest 注入到请求范围的 bean 中?【英文标题】:Spring: how do I inject an HttpServletRequest into a request-scoped bean? 【发布时间】:2011-03-20 05:44:05 【问题描述】:我正在尝试在 Spring 中设置 request-scoped bean。
我已成功设置,因此每个请求都会创建一次 bean。现在,它需要访问 HttpServletRequest 对象。
由于每个请求都会创建一次 bean,我认为容器可以轻松地将请求对象注入到我的 bean 中。我该怎么做?
【问题讨论】:
【参考方案1】:Spring 通过 ServletRequestAttributes
类型的 wrapper 对象公开当前的 HttpServletRequest
对象(以及当前的 HttpSession
对象)。这个包装器对象绑定到ThreadLocal,通过调用static
方法RequestContextHolder.currentRequestAttributes()
获得。
ServletRequestAttributes
提供了方法getRequest()
获取当前请求,getSession()
获取当前会话和其他方法获取存储在两个范围中的属性。以下代码虽然有点难看,但应该可以让您在应用程序的任何位置获取当前请求对象:
HttpServletRequest curRequest =
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
注意RequestContextHolder.currentRequestAttributes()
方法返回一个接口,需要类型转换为实现该接口的ServletRequestAttributes
。
Spring Javadoc: RequestContextHolder | ServletRequestAttributes
【讨论】:
注入是很好的解决方案,但我发现 MockMvc 测试注入 HttpServletRequest 的 Spring 验证器存在问题。因此,如果您希望模拟测试和生产代码都正常运行,这应该是选择。 @Neyko 为什么会这样?对于模拟测试(单元测试?),你可以注入模拟 HttpServletRequest 或任何你想要的......不是吗?或者你可以使用 MockHttpServletRequest 我猜? 在单例范围的服务实例中使用安全吗?【参考方案2】:请求范围的 bean 可以与请求对象自动装配。
private @Autowired HttpServletRequest request;
【讨论】:
有老式的 XML 方法吗? 对我不起作用(spring mvc 3.1)-也许还有更多需要做的事情?采用 Samit 的解决方案。 问题是当您使用 MockMvc 和这种注入测试验证器时,您会遇到问题。在这种情况下可能会首选其他解决方案 也可以将 HttpServletRequest 自动装配到非请求范围的 bean 中,因为对于 HttpServletRequest,Spring 将生成一个代理 HttpServletRequest,它知道如何获取请求的实际实例。因此,即使您的控制器是单例范围的,自动连接请求也是安全的。 警告 Spring 自动装配将无法运行测试。【参考方案3】:按照here 的建议,您也可以将HttpServletRequest
作为方法参数注入,例如:
public MyResponseObject myApiMethod(HttpServletRequest request, ...)
...
【讨论】:
以上是关于Spring:如何将 HttpServletRequest 注入到请求范围的 bean 中?的主要内容,如果未能解决你的问题,请参考以下文章