Java EE 6:如何将ServletContext注入托管bean

Tha*_*ham 5 jsf servlets java-ee java-ee-6

(使用Glassfish 3.1的Java EE 6)

我有一个属性文件,我想在启动时只处理一次,所以我这样做了

public class Config implements ServletContextListener{

    private static final String CONFIG_FILE_PATH = "C:\\dev\\harry\\core.cfg";

    private static final String CONFIG_ATTRIBUTE_NAME = "config";

    private long startupTime;

    private ConfigRecord config;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        this.startupTime = System.currentTimeMillis() / 1000;
        this.config = new ConfigRecord(CONFIG_FILE_PATH); //Parse the property file
        sce.getServletContext().setAttribute(CONFIG_ATTRIBUTE_NAME, this);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //Nothing to do here
    }

    public ConfigRecord getConfig() {
        return config;
    }

    public long getStartupTime() {
        return startupTime;
    }
}
Run Code Online (Sandbox Code Playgroud)

web.xml,我注册如下

<listener>
    <listener-class>com.wf.docsys.core.servlet.Config</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)

现在我如何ConfigRecord config从托管bean 访问它.我试试这个

@ManagedBean
@RequestScoped 
public class DisplayInbound {

    @EJB
    private CoreMainEJBLocal coreMainEJBLocal;

    @javax.ws.rs.core.Context
    private ServletContext servletContext;

    public void test(){
        Config config = (Config) servletContext.getAttribute("config")
        ConfigRecord configRecord = config.getConfig();
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为它不起作用.有NullPointerException.

Bal*_*usC 11

@Context注释仅适用于JAX-RS控制器,而不适用于JSF托管bean.你必须@ManagedProperty改用.该ServletContext可通过ExternalContext#getContext().它FacesContext本身可用#{facesContext}.

@ManagedProperty(value="#{facesContext.externalContext.context}")
private ServletContext context;
Run Code Online (Sandbox Code Playgroud)

或者因为您将侦听器存储为servletcontext属性(与JSF应用程序范围基本相同),您还可以通过其属性名称将其设置为托管属性:

@ManagedProperty(value="#{config}")
private Config config;
Run Code Online (Sandbox Code Playgroud)

但是,由于你使用的是JSF 2.0,我建议使用一个热切构造的代替.使用和在这样的bean中,你在webapp的启动和关闭方面有类似的钩子.@ApplicationScoped @ManagedBean@PostConstruct@PreDestroyServletContextListener

@ManagedBean(eager=true)
@ApplicationScoped
public void Config {

    @PostConstruct
    public void applicationInitialized() {
        // ...
    }

    @PreDestroy
    public void applicationDestroyed() {
         // ...
    }

}
Run Code Online (Sandbox Code Playgroud)

您可以通常的@ManagedProperty方式将其注入另一个bean中,并以通常的EL方式在视图中访问它.