在CDI SessionScoped bean中注入HttpServletRequest

我有一个会话范围的CDI bean,我需要以某种方式访问​​这个bean的@PostConstruct方法中的HttpServletRequest对象。 可能吗? 我试过注入这样一个对象,但结果是:

 WELD-001408 Unsatisfied dependencies for type [HttpServletRequest] with qualifiers [@Default] at injection point [[field] @Inject ...] 

正如我在google搜索中所理解的那样,Seam框架具有这样的function,但我在GlassFish服务器上有一个标准的Java EE应用程序。

是否有可能以某种方式将请求传递给CDI bean的@PostConstruct方法?

根据您的评论,您希望访问用户主体。 你可以像这样注入它: @Inject Principal principal;@Resource Principal principal; ,请参阅Java EE 6教程 。

更新

我会回答你的直接问题。 在Java EE 7(CDI 1.1)中,支持开箱即用的HttpServletRequest注入。 但是,在Java EE 6(CDI 1.0)中,不支持开箱即用。 要使其正常运行,请将以下课程添加到您的网络应用中:

 import javax.enterprise.inject.Produces; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; @WebListener public class CDIServletRequestProducingListener implements ServletRequestListener { private static ThreadLocal SERVLET_REQUESTS = new ThreadLocal<>(); @Override public void requestInitialized(ServletRequestEvent sre) { SERVLET_REQUESTS.set(sre.getServletRequest()); } @Override public void requestDestroyed(ServletRequestEvent sre) { SERVLET_REQUESTS.remove(); } @Produces private ServletRequest obtain() { return SERVLET_REQUESTS.get(); } } 

注意:仅在GlassFish 3.1.2.2上测试

使用rdcrng中的代码时请注意以下事项:
* producer-method obtain是依赖范围的,因此只对应用程序作用域bean调用一次(并且将解决除第一个之外的所有其他请求的问题)
*您可以使用@RequestScoped解决此问题
*当RequestScoped注释时,您将只获得一个代理,因此您无法将其添加到HttpServletRequest。 所以你可能想要一个HttpServletRequest的制作人。

另请注意:根据CDI规范链接段 3.6,java ee bean不是托管bean。 因此,您最终会得到两个CDIServletRequestProducingListener实例 – 一个由Java EE容器管理,一个由CDI容器管理。 它只能起作用,因为SERVLET_REQUESTS是静态的。

为方便起见,修改后的代码。

 import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.Produces; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServletRequest; @WebListener public class CDIServletRequestProducingListener implements ServletRequestListener { private static ThreadLocal SERVLET_REQUESTS = new ThreadLocal(); @Override public void requestInitialized(ServletRequestEvent sre) { SERVLET_REQUESTS.set(sre.getServletRequest()); } @Override public void requestDestroyed(ServletRequestEvent sre) { SERVLET_REQUESTS.remove(); } @RequestScoped @Produces private HttpServletRequest obtainHttp() { ServletRequest servletRequest = SERVLET_REQUESTS.get(); if (servletRequest instanceof HttpServletRequest) { return (HttpServletRequest) servletRequest; } else { throw new RuntimeException("There is no HttpServletRequest avaible for injection"); } } 

}