6

I just started learning JSF.

While working with an example, I felt the need to access the ServletContext object inside MyBean class. I wanted to use an object which I had put inside the ServletContext using Listener. Can I do that? Does ServletContext has its scope inside Beans as well?

Jazib
  • 1,200
  • 1
  • 16
  • 39

1 Answers1

15

It's just available by ExternalContext#getContext(). See also its javadoc:

getContext

public abstract java.lang.Object getContext()

Return the application environment object instance for the current appication.

It is valid to call this method during application startup or shutdown. If called during application startup or shutdown, this returns the same container context instance (ServletContext or PortletContext) as the one returned when calling getContext() on the ExternalContext returned by the FacesContext during an actual request.

Servlet: This must be the current application's javax.servlet.ServletContext instance.

So, this should do:

public void someMethod() {
    ServletContext servletContext = (ServletContext) FacesContext
        .getCurrentInstance().getExternalContext().getContext();
    // ...
}

Unrelated to the concrete question, depending on the concrete functional requirement, this may not be the right solution to the concrete problem. General consensus is that your JSF code should be as much as possible free of any javax.servlet.* dependencies/imports. Your question isn't exactly clear, but if you indeed intend to access an attribute which you've put in the servlet context, then just get it from ExternalContext#getApplicationMap() instead.

E.g. in the ServletContextListener:

event.getServletContext().setAttribute("foo", foo);

and then in JSF

Foo foo = (Foo) FacesContext.getCurrentInstance().getExternalContext()
    .getApplicationMap().get("foo");

or even just by @ManagedProperty

@ManagedProperty("#{foo}")
private Foo foo; // +setter
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • The concrete problem was that I was instantiating a Database Connection and storing that connection object in Context-param so that all Servlets could use it. Seeing your answer, I guess the ExternalContext class would do the job in JSF. I'll check it after going through the docs. Thank you :) – Jazib Jan 09 '13 at 20:36
  • You're welcome. Well, this is honestly said kind of "eeek". This way your application would die after ~8 hours of running depending on the DB server side connection timeout setting. You should open and close DB resources in shortest possible scope. See also among others http://stackoverflow.com/questions/9428573/is-it-safe-to-use-a-static-java-sql-connection-instance-in-a-multithreaded-syste/9431863#9431863. However, for a Java EE web application, I'd have used JPA `@EntityManager` in an `@Stateless` EJB. This is injectable in both JSF managed beans and servlets by just `@EJB`. – BalusC Jan 09 '13 at 20:38