在CDIBean的非请求环境中获取JSF ServletContext

在CDIBean的非请求环境中获取JSF ServletContext,jsf,cookies,initialization,cdi,Jsf,Cookies,Initialization,Cdi,我正在使用TOME+1.7.1。 对于JSF托管bean,此代码运行良好: @ManagedBean( eager = true ) @ApplicationScoped public class AppBean { @PostConstruct public void init() { ServletContext sc = (ServletContext) FacesContext.getCurrentInstance().getExternalContex

我正在使用TOME+1.7.1。 对于JSF托管bean,此代码运行良好:

@ManagedBean( eager = true )
@ApplicationScoped
public class AppBean {

    @PostConstruct
    public void init() {
        ServletContext sc = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
        if (GlobalSettings.TESTMODE) {
            sc.getSessionCookieConfig().setDomain("." + GlobalSettings.APP_DOMAIN_TEST);
        } else {
            sc.getSessionCookieConfig().setDomain("." + GlobalSettings.APP_DOMAIN);
        }
    }
}
init函数在应用程序启动时运行,ServletContext可用

我到处都读到,是时候迁移到CDIBeans而不是JSFBeans了。所以我想把
@ManagedBean(eager=true)
改为
@Named@eager
(@eager来自Omnifaces)。Init函数在应用程序启动时运行,但没有FacesContext,因此无法获取ServletContext

一般问题:如何在CDIBeans中的非请求环境中获取ServletContext?(ServletContext不是“每个请求”对象,因此它应该在第一个请求之前存在。)

特定问题:如何在第一个请求发生之前从代码中动态设置会话cookie的域?

您应该使用,以便在基于servlet的应用程序上执行编程配置

@WebListener
public class Config implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
        ServletContext servletContext = event.getServletContext(); 
        // ...
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        ServletContext servletContext = event.getServletContext(); 
        // ...
    }

}
@WebListener
本身也是CDI管理的,因此您可以使用
@Inject
和其中的好友


应用程序范围的托管bean用于保存应用程序范围的数据/状态,这些数据/状态可以在请求/视图/会话之间使用/共享。

根据CDI规范,您可以
@将
ServletContext
注入CDI bean。只需确保在
@PostConstruct
中执行此操作,因为注入的字段只有在构建之后才可用:

@Inject ServletContext extCtxt;

@PostConstruct
public void doSomething(){
  // do something with your injected field
}