5

In my Java EE 6-webapp (running on latest GlassFish 3.1), I'm using JSF2-ManagedBeans and @ManagedProperty to inject them into other ManagedBeans. Now i would like to know if i can also inject a @ManagedBean into a @WebServlet, using @ManagedProperty. Some code:

@WebServlet(name = "vdd")
public class VddServlet extends HttpServlet
{
  @ManagedProperty(value = "#{userIdentity}")
  private UserIdentity identity;
}

The ManagedBean looks like this:

@ManagedBean
public class UserIdentity 
{
  ...
}

Does it work like this? If not, what other ways do i have to inject a ManagedBean into a WebServlet (without CDI, which is currently not an option - since there are some issues in GF 3.1 B32/33 in combination with OSGi-Java EE-apps, but we are short on time)?

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Wolkenarchitekt
  • 20,170
  • 29
  • 111
  • 174
  • @Vladimir i just did a test with a Netbeans sampleapp (PetCatalog), created a Servlet, annotated it with @WebServlet, injected a @ManagedBean into it. When opening the servlet in a Browser, the value is NOT injected, so it seems as it doesn't work this way. Need help on this... – Wolkenarchitekt Dec 17 '10 at 10:16
  • why do you want bean injected in servlet ? if you want to just access it you can access it from `FacesContext` – jmj Dec 17 '10 at 10:20
  • Ok that would be possible. But doing it by Injection would be much nicer. No way to do that without CDI? – Wolkenarchitekt Dec 17 '10 at 10:30

1 Answers1

7

Using @ManagedProperty in a servlet is not possible since this works in @ManagedBean classes only. Further, injecting an object which has a lesser scope than the parent itself is also not possible since that would also only end up in concurrency problems. The injector would throw a runtimeexception for that. A servlet is in essence application scoped and shared among all users and your UserIdentity bean seems to be session scoped.

Since JSF runs on top of the Servlet API and stores the session scoped beans in, well, the session, you could in the servlet just grab it as session attribute:

UserIdentity identity = (UserIdentity) request.getSession().getAttribute("userIdentity");

Note that the FacesContext is usually also not available in a servlet other than FacesServlet, so using FacesContext in the servlet as suggested in a comment does not make any sense, that would only return null.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    Thanks! Okay i'm now doing the lookup like this for my session scoped beans. But what about my Request scoped Managed beans? How can i access them from my servlet? – Wolkenarchitekt Dec 17 '10 at 12:29
  • In theory, it would be available as request attribute (and in the same line, application scoped beans are available as servletcontext attribute). But normally you don't run both a homegrown servlet and the facesservlet in the same request (so managed bean would be null in servlet). Just pass the data of interest around as request parameters instead. – BalusC Dec 17 '10 at 12:32
  • Ok, so my request scoped bean should be available in my Servlet by calling request.getServletContext().getAttribute(nameOfRequestScopedManagedBean) or request.getAttribute(nameOfRequestScopedManagedBean), right? – Wolkenarchitekt Dec 17 '10 at 12:38
  • 1
    Request scoped beans are available as request attribute (which would usually return `null` because the servlet usually runs in a different request). Application scoped beans are available as servletcontext (application) attribute. Is it now all logical and clear? – BalusC Dec 17 '10 at 12:39
  • Ok thanks, pretty clear now. As the RequestScoped MB is not accessible, I'll convert the RequestScoped bean to an EJB. that way i can inject it with @EJB into my Servlet. – Wolkenarchitekt Dec 17 '10 at 12:47
  • If it's really a stateless bean (i.e. you could make it session or application scoped without any problems), then you can go ahead. A request scoped bean usually indicates that you want a request scoped state, so I didn't suggest that immediately. – BalusC Dec 17 '10 at 12:49
  • Good point. The bean is stateful, so i have a similar problem again. I'm working around this by converting the bean to a regular Java-class. Now i'm creating an instance of that bean inside my Servlet, and handing over the EJB-injections that the bean needs (persistence) during the construction of that object. – Wolkenarchitekt Dec 17 '10 at 12:58
  • Also remember that if you're injecting a stateless session bean into a servlet, a single stub (proxy) for this bean will be shared between all requests. Normally this shouldn't be a problem, but it can't hurt to be aware of this. – Arjan Tijms Dec 19 '10 at 14:56