Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java EE 6: How to inject ServletContext into managed bean

(Java EE 6 with Glassfish 3.1)

I have a property file that I want to process only once at start up time, so I did this

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;
    }
}

and in web.xml, i register it as follow

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

Now how do I access the ConfigRecord config from the managed bean. I try this

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

I dont think it work. Got NullPointerException.

like image 401
Thang Pham Avatar asked Jun 27 '11 18:06

Thang Pham


1 Answers

That @Context annotation is only applicable in a JAX-RS controller, not in a JSF managed bean. You have to use @ManagedProperty instead. The ServletContext is available by ExternalContext#getContext(). The FacesContext itself is available by #{facesContext}.

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

Or because you stored the listener as a servletcontext attribute, which is basically the same as the JSF application scope, you could also just set it as managed property by its attribute name:

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

But since you're on JSF 2.0, I'd suggest to use an @ApplicationScoped @ManagedBean instead which is eagerly constructed. With @PostConstruct and @PreDestroy in such a bean you have similar hooks on webapp's startup and shutdown as in a ServletContextListener.

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

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

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

}

You can inject it in another beans the usual @ManagedProperty way and access it in the views the usual EL way.

like image 200
BalusC Avatar answered Nov 15 '22 08:11

BalusC