【问题标题】:Java EE 6: How to inject ServletContext into managed beanJava EE 6:如何将 ServletContext 注入托管 bean
【发布时间】:2011-06-27 18:20:00
【问题描述】:

(带有 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;
    }
}

web.xml,我注册如下

<listener>
    <listener-class>com.wf.docsys.core.servlet.Config</listener-class>
</listener>

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

@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();
    }
}

我认为它不起作用。得到NullPointerException

【问题讨论】:

    标签: jsf jakarta-ee java-ee-6 servlets


    【解决方案1】:

    @Context 注释仅适用于 JAX-RS 控制器,不适用于 JSF 托管 bean。您必须改用@ManagedPropertyServletContext 可通过ExternalContext#getContext() 获得。 FacesContext 本身可通过#{facesContext} 获得。

    @ManagedProperty(value="#{facesContext.externalContext.context}")
    private ServletContext context;
    

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

    @ManagedProperty(value="#{config}")
    private Config config;
    

    但由于您使用的是 JSF 2.0,我建议您使用 @ApplicationScoped @ManagedBean 来代替它,它是急切构建的。在这样的 bean 中使用 @PostConstruct@PreDestroy 时,您在 webapp 的启动和关闭上会有类似的钩子,就像在 ServletContextListener 中一样。

    @ManagedBean(eager=true)
    @ApplicationScoped
    public void Config {
    
        @PostConstruct
        public void applicationInitialized() {
            // ...
        }
    
        @PreDestroy
        public void applicationDestroyed() {
             // ...
        }
    
    }
    

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

    【讨论】:

      猜你喜欢
      • 2014-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-12
      • 2012-06-22
      • 1970-01-01
      • 2023-03-27
      • 2018-06-22
      相关资源
      最近更新 更多