Java EE 6: как внедрить ServletContext в управляемый компонент - PullRequest
5 голосов
/ 27 июня 2011

(Java EE 6 со Glassfish 3.1)

У меня есть файл свойств, который я хочу обработать только один раз при запуске, поэтому я сделал это

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>

Теперь, как мне получить доступ к 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.

1 Ответ

11 голосов
/ 27 июня 2011

Это примечание @Context применимо только в контроллере JAX-RS, но не в управляемом компоненте JSF.Вместо этого вы должны использовать @ManagedProperty.ServletContext доступен по номеру 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 вместо этого, который охотно построен.С @PostConstruct и @PreDestroy в таком бине у вас есть такие же зацепки при запуске и завершении работы веб-приложения, как и в ServletContextListener.

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

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

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

}

Вы можете ввести его в других бобах обычным @ManagedProperty способом и получить к нему доступ в представлениях обычным способом EL.

...