如何在CDI中注入并判断HttpServletRequest是否存在(适配请求内外调用)
解决Weld中Instance在请求外的判断问题
我懂你碰到的这个坑——用Instance<HttpServletRequest>的isUnsatisfied()来判断是否处于HTTP请求上下文里完全不好使,对吧?哪怕不在请求中,这个方法还是返回false,但一调用get()就直接抛出那个WELD-000710异常,简直离谱。
问题出在哪
这是因为Instance.isUnsatisfied()检查的是有没有符合类型的bean定义,而不是当前上下文能不能提供这个bean的实例。HttpServletRequest是标准的request-scoped bean,Weld清楚它的存在,所以isUnsatisfied()永远返回false;但当没有活跃的HTTP请求上下文时,硬要拿实例肯定会失败。
靠谱的解决办法
这里有几种实用的方式,能帮你正确判断当前是否在请求上下文里,并且安全获取HttpServletRequest:
方案1:检查请求上下文是否活跃
注入BeanManager,用它来判断request scope是否处于活跃状态:
@Inject private BeanManager beanManager; @Inject private Instance<HttpServletRequest> httpReq; void doSomethingIfInRequest() { // 先确认request scope是否活跃 if (!beanManager.isActive(RequestScoped.class)) { return; } HttpServletRequest request = httpReq.get(); // 在这里处理请求相关逻辑 }
方案2:用try-catch包裹获取操作
虽然看起来有点“笨办法”,但胜在简单直接——既然知道请求外调用get()会抛异常,那就直接捕获:
@Inject private Instance<HttpServletRequest> httpReq; void doSomethingIfInRequest() { HttpServletRequest request; try { request = httpReq.get(); } catch (IllegalStateException e) { // 不在请求上下文里,直接返回 return; } // 处理请求逻辑 }
方案3:用Weld专属的RequestContextController
如果你的项目用的是Weld,可以注入RequestContextController来判断上下文是否激活:
@Inject private RequestContextController requestContextController; @Inject private Instance<HttpServletRequest> httpReq; void doSomethingIfInRequest() { if (!requestContextController.isActive()) { return; } HttpServletRequest request = httpReq.get(); // 处理逻辑 }
额外小提示
如果你只是偶尔需要获取请求信息,也可以考虑用HttpServletRequest的代理,但要注意:代理在请求外调用方法还是会抛异常,所以还是得先判断上下文状态才行。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

