Learning JSF2: Managed beans

I’m starting a series called Learning JSF 2 on my blog. It will cover JSF 2 with emphasis on new features. Every post will cover a different features, the first one covers managed beans.

Managed bean is a regular Java bean with a fancy name. When we register the bean with JSF it becomes a managed bean, in other words, it’s now managed by the framework (JSF). In JSF, managed beans are used as model for UI components. In JSF 1.2, for a bean to become a managed bean, you had to register it in JSF configuration file such as faces-config.xml. One of the biggest announces was that as the number of beans grew, the JSF configuration file grew as well, and it was difficult to keep track of all names annd changes in three different files that all were “connected” (JSF configuration file, the JSF view and the bean itself).

Luckily, JSF 2 team has introduced annotations to register managed beans. With annotations, the bean and its registration are in the same place (Java class) so it becomes much easier to manage. You can still use JSF configuration file to register managed beans, and in some cases as you will see it’s the only way. Let’s start.

Basic Configuration

In JSF 1.2, the simplest registration looks like this:


  userBean
  example.UserBean
  request

Exactly the same registration in JSF 2 looks like this:

package example;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name="userBean")
@RequestScoped
public class UserBean {

   private String name;

   public String getName() {
	return name;
   }
   public void setName(String name) {
	this.name = name;
   }
   public UserBean() {}
}

JSF 2 introduces @ManagedBean and @RequestScoped annotations.

@ManagedBean – marks this bean to be a managed bean with the name specified in name attribute. If the name attribute in @ManagedBean is not specified, then the managed bean name will default to class name portion of the fully qualified class name. In this case it would be userBean. For example, this is the same as above:

@ManagedBean
@RequestScoped
public class UserBean {
   ...
}

@RequestScoped – sets the scope (request) into which this bean will be placed. If scope is not specified then bean will default to request scope. So we can write this:

@ManagedBean
public class UserBean {
   ...
}

My recommendation is to always write name and scope to make it easier to read and understand the code.

All scope annoations in JSF 2: @NoneScoped, @RequestScoped, @ViewScoped, @SessionScoped, @ApplicationScoped, and @CustomScope. @ViewScoped and @CustomScoped are new scopes in JSF 2 . I will cover @ViewScoped later in this post and @CustomScoped in another post.

@ManagedBean also has eager attribute (new in JSF 2). If eager=”true” and scope is application, then this bean must be created when the application starts and not during the first reference to the bean. In other words, the creation and storing of the bean instance must happen before any requests are serviced.

@ManagedBean(name="globalBean", eager=true)
@ApplicationScoped
public class GlobalBean {
 ...
}

If eager is true but scope is not application, then regular “lazy” initialization used. If eager is not defined or missing, then “lazy” initialization is used as well.

Using Managed Properties (or initialising bean properties)

To mark a bean property to be managed property, @ManagedProperty annotations is available:

@ManagedProperty(value="Mia")
private String name;

When the bean is created, ‘Mia’ will be passed to setName(..) method.

Dependency Injection

JSF is a basic Dependency Injection (DI) container and we can use annotations to inject objects. JSF offers setter method injection – this means the object will be passed into the setter. It is also static injection – meaning, the injection will happen only during bean creation (as opposed to Seam, where static and dynamic injection is possible).

Suppose we want to inject userManager into userBean:

@ManagedBean(name="userManager")
@SessionScoped
public class UserManager {

   private List  users;

   public List getUsers() {
	   return users;
   }
   ...
}

Notice that we are using EL for the ManagedProperty.

@ManagedBean(name="userBean")
@RequestScoped
public class UserBean {
   @ManagedProperty(value="#{userManager}")
   private UserManager userManager;

   public UserManager getUserManager() {
	return userManager;
   }
   public void setUserManager(UserManager userManager) {
	this.userManager = userManager;
   }
   ...
}

In JSF 1.2, this would look like this:


  userBean
  example.UserBean
  request
  
   userManager
   example.UserManager
   #{userManager}
  
 

Still Need JSF Configuration File

Annotations definitely make life easier, however, there are some cases where JSF configuration file is still needed when working with managed beans (Note: I’m only refering to managed bean configuration, not to such things as navigation, locales, etc).

When you want to initialise a property such as list or map, it is still can only be done in JSF configuration file.

public class UserBean {
   private List hobbies;
   private Map favoriteSites;
   // gettter and setter for both fields...
}

JSF configuration file:

 
  userBean
  example.UserBean
  request
  
   hobbies
   java.util.List
   
   	Swimming
   	Running
   	Dancing
   	JSF
   
  
  
   favoriteSites
   java.util.Map
   
   	
   		site1
   		www.google.com
   	
   	
   		site2
   		www.yahoo.com
   	
   
  
 

You will see that we moved the entire bean configuration into JSF configuration file now. It’s not possible to register the bean via annotations and then create managed properties in JSF configuration file. If you use annotations and then register the bean in JSF configuration file, then the registration in JSF configuration file will overwrite the annotations one.

View Scope

View scope is new scope in JSF 2. It will keep the bean alive as long as you are staying on the same view (page). I blogged about view scope in RichFaces here that you can use today with JSF 1.2.

The bean is saved as an attribute of the JSF view. When the JSF view (its state) is saved, the bean is saved as well. When the view is restored, the bean is restored and placed back in request scope.

View scope is very handy when editing a page with a list of objects. For example:

screenshot_023

@ManagedBean(name="userList")
@ViewScoped
public class UserList {

   private ArrayList users;
   private String selectedUser;

   @PostConstruct
   public void create (){
	users = new ArrayList  ();
	users.add("John");
	users.add("Charley");
	users.add("Priscila");
	users.add("Kate");
	users.add("Emily");
	users.add("Barack");
	users.add("Mia");
	users.add("Arthur");
   }
   public void delete (){
	users.remove(selectedUser);
   }
   public String getSelectedUser() {
	return selectedUser;
   }
   public void setSelectedUser(String selectedUser) {
	this.selectedUser = selectedUser;
   }
   public ArrayList getUsers() {
	return users;
   }
}

JSF view:


   
      
  	   
  		
  	   
      
      
  		
       
   

That’s it for the first entry in Learning JSF 2.

72 Comments

  1. Ed Burns says:

    Great post, Max. Hope to see you (and maybe your family) in Orlando in December.

  2. Matthias Wessendorf says:

    Nice post!

    I am actually very happy that there is something like the View Scope – as you say it _is_ very handy!

    -Matthias

  3. sboulay says:

    Also, I believe you can now use el method invocation so you don’t have to have a selectedUser property in your backing bean. You can simply do the following

    and in your backing bean …

    public void selectedUser(String selectedUser) {
    this.selectedUser = selectedUser;
    }

    http://weblogs.java.net/blog/cayhorstmann/archive/2009/07/say_sayonara_to_1.html

  4. Kamel says:

    very interesting thank you for sharing.

  5. max says:

    @sboulay: Yes, you can do that with EL 2.0

  6. max says:

    @sboulay: Sorry, it’s not 2.0, it’s 2.1 MR: http://jcp.org/aboutJava/communityprocess/maintenance/jsr245/245-MR2_2.html . 2.1 is the current version.

  7. Thai Dang Vu says:

    I heard that we can use arguments in server method calls with JSF 2. That means we can write

    instead of

    Am I right?

  8. max says:

    @Thai – please report, I don’t see the code. Post your code via http://tinypaste.com .

  9. Good article 🙂 Go on Max

  10. arun says:

    Appreciate the effort to put together info on whats new. Though it would be nice if managing properties passed to managed beans through annotations is externalised instead to harcoding in the java beans.

  11. mohsin says:

    Nice post Max

  12. mota_ningy says:

    I have looked at numerous blogs online to find out the reasons why my managedBeans are not scanned, to no avail. I saw something about JSF 2.0 scanning only particular directories namely,

    1. WEB-INF/classes
    2. JARS in WEB-INF/lib
    3. classpath with META-INF/faces-config.xml

    but my web module directory structure, same as that provided by maven webapp is not being scanned. I am using embedded tomcat as my development server. Is there something I am doing wrong here? Thanks in advance for you help.

  13. max says:

    @mota_ningy: I never tried running with embedded Tomcat. It should work fine if you deploy in standard way to Tomcat.

  14. Armin says:

    Thank’s for the info about how to use an button in the dataTable.

  15. Madalina says:

    Very usefull information, thank you!

  16. jmcubel says:

    Good post Max,

    One question. Is it posible to inject a ViewScoped bean into a RequestScoped bean? I’m getting this exception…

    java.lang.NullPointerException
    at com.sun.faces.mgbean.BeanManager$ScopeManager$ViewScopeHandler.isInScope(BeanManager.java:552)
    at com.sun.faces.mgbean.BeanManager$ScopeManager.isInScope(BeanManager.java:464)
    at com.sun.faces.mgbean.BeanManager.isBeanInScope(BeanManager.java:236)
    at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:82)
    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)

  17. max says:

    @jmcubel: it should be possible to inject a ViewScoped bean into RequestScoped bean but I don’t know why you are getting this exception.

  18. jmcubel says:

    The problem is because viewRoot is null when method ViewScopeHandler.isInScope() is called (I’m using mojarra 2.0.2-FCS):

    private static class ViewScopeHandler implements ScopeHandler {

    public void handle(String name, Object bean, FacesContext context) {

    context.getViewRoot().getViewMap().put(name, bean);

    }

    public boolean isInScope(String name, FacesContext context) {

    Map viewMap = context.getViewRoot().getViewMap(false);
    return ((viewMap != null) && viewMap.containsKey(name));

    }

    public Object getFromScope(String name, FacesContext context) {

    Map viewMap = context.getViewRoot().getViewMap(false);
    return ((viewMap != null) ? viewMap.get(name) : null);

    }

    } // END ViewScopeHandler

  19. bfabian says:

    I hope I’m not off topic.

    How to use two or more scopes in a page without conflicting each other?

    BTW I would like to use Request and Session at the same time.

  20. max says:

    @bfabian: you have two beans, one is in session scope, one is in request scope and both are bound to the same page. Scope is a property of a bean, not the page itself. Hope this helps.

  21. hybris says:

    @jmcubel

    hey, did you manage to underdant why you were getting that exception?
    i am in a similar situation and i can’t find a way out

  22. Mayank Modi says:

    Nice Post Max.

    I have one query here.

    As you mentioned, “@ManagedBean also has eager attribute (new in JSF 2). If eager=”true” and scope is application, then this bean must be created when the application starts and not during the first reference to the bean.” so at this time any method (e.g. x()) having annotation post-construct will execute.

    So while execution of x is there any possible way to get context path. Servlet context is not available at this time, so is there any other way..

    Thanks in Advance..

    Currently I wrote something like this which didn’t work…

    @PostConstruct
    public void constructMessageBundle() {

    ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
    String path = servletContext.getRealPath(“WEB-INF” File.separator “classes” File.separator);
    }

  23. max says:

    @Mayank Modi: I think the code that you have should work.

  24. Fran Serrano says:

    Great post!! Really nice summary of what a just started JSF developer would look for.
    I’m recently migrating from Spring IOC/MVC to Spring IOC/JSF/IceFaces and this post is making my life a lot easier.

    Thanks a lot!

  25. mpunktw says:

    I’ve got a simple but solution-resistent problem. Following simple code-fragment
    @ManagedBean
    @SessionScoped
    public class xxx {

    @ManagedProperty(value = “21”)
    private int wert;

    Always delivers:
    Managed Bean xxx can not be created. Following problem were found: – Property wert for Managed Bean xxx is not present.
    (I translated the error message from German, please take this under consideration)

    I tried everything! Whats my mistake???!

  26. max says:

    @mpunktw: do you have a setter for the property?

  27. mpunktw says:

    OMG … that’s the problem! Thanks!!!!

  28. Franklin says:

    Seems like the XML was taken off here it is again

    I seem to have a problem with ViewScope beans that are created with
    lessthan ui:include src=”#{indexBean.selectedPage}” greaterthan lessthan /ui:include greater than
    The bean created at the src url is not reconstructed unless you do a page refresh with F5. I am looking at getting it reconstructed with AJAX. Any hints on this ?

    Regards,
    Franklin

  29. max says:

    @Franklin: it’s not created on first page load or when you send an Ajax request and render that area?

  30. bashan says:

    Simply a great post!

  31. Filipe Santana says:

    Hi! you have great articles on jsf2! I’m learning a lot, thank you!

    I’d like to know the relationship between “UserManager”(session scope) and “UserBean”(request) in a real application. I’m implementing a login and I’m wondering if it will be nice for me to comprehend it.

    Thanks again!

  32. max says:

    @Filipe: They are both managed beans, one will be placed in session scope when created, the other one will be placed in request scope when created. The session scoped bean will be available as long as the session is active. The request scoped bean – a new instance will be created for each request. In the example, I inject the session scoped bean into request scoped bean. Every new request (and thus new bean) will get the same instance of the session bean. Does this help?

  33. Filipe Santana says:

    Hi max! Thanks! I think I understood. So there’ll be just one session scoped bean per session (UserManager) and many request scoped bean per session (UserBean). Each one of these request scoped bean (UserBean) will have as property the same session bean (UserManager). Please correct me if I was wrong.

    Now, I’d like to know what is the best or common approach when you are programming a login. If I understand that right, I’ll can’t have a session bean because I’ll have many users login in, so I’ll need a request bean for the users?

    Thanks a lot for your help!

  34. Filipe Santana says:

    Sorry I forgot to notify the follow up, please disconsider this post.

  35. max says:

    @Filipe: Yes, correct to the first part. Login information you could keep in session as you probably will need it throughout the session. If you need to keep a list of users or orders (or similar), then you might consider holding them in session if you need frequent access to them. This is just very general advice, it very much depends on your application.

  36. Filipe Santana says:

    @max: Thank you! In my app I’ll need frequent access to the login information (in my case the user), so I’ll keep in the session scoped.

    Just a question , if I have:

    @ManagedBean @SessionScoped
    public class User { … a doLogin method here… }

    For each user that login in my app, a new bean (User, see above) will be created? And all these beans created will be available for the entire session?

    Thanks again!

  37. max says:

    @Filipe: Yes, you will have one User object for the entire session.

  38. Filipe Santana says:

    @max: Just one? I thought that I’ll have as many as users logged in my app…

    for example:

    client one = 1 user object for the entire session
    client two = 1 user object for the entire session
    client three = 1 user object for the entire session

    Total = 3 users objects!

    Thanks for your patient and kindness!

  39. max says:

    @Filipe: Yes, that’s correct. Each client will have one User object.

  40. Filipe Santana says:

    @max: OK, thank you!

  41. Great post. Really good information.

  42. John Ortiz says:

    Thanks for this introduction. It was useful for me. So long.

  43. jdeveloper says:

    hi i’m new in jsf when i use @managedbean(name=”user”) and in the index.xhtml write

    it doesn’t know what is the “user”? but when i used configuration file it work well why?

    1. max says:

      @jdevfeloper: check your code carefully, one thing is that is should be @ManagedBean.

  44. Ankit says:

    Hi max,It is awesome tutorial to understand annotations in jsf.
    thanks a lot.

  45. Simon says:

    Is there a way to keep track of FacesContext after restarting Tomcat? For example: I am logged in. Server is being updated and restarted. The UserSessionBean keeps the Login alive. But message properties from ResourceBundle need FacesContext.getCurr… to be able to show the right message. FacesContext is not serializable and i guess extending it, making the child class serializable is not a good idea (i do not want to change everything in the code, where facescontext is used, and i do not know what jsf does with FacesContext). So is there a way to somehow serialize the faces context?
    Cheers!

    1. max says:

      You would need to save it some where.. so you would need to serialize it. As for the actual implementation, don’t have it.

      1. Simon says:

        save it somewhere? i don’t get it. You think I should save the FacesContext each time it is used? That would be a huge overhead, wouldn’t it?

      2. max says:

        I meant to save it between Tomcat restarts. You might be better advice on JSF specific forum. I haven’t been working with JSF for the past year.

      3. Simon says:

        Ok. Thanks for your reply anyways.

  46. savitha says:

    most useless and confusing tutorial i have ever read.

  47. Brian says:

    Very good tutorial. Very useful. (Can’t imagine why some people’s comprehension is so limited.)

  48. Kpanchan says:

    Well written article with great summary of each features explained detail.

  49. Matt says:

    Great post, keep up the good work. savitha, what planet are you from?

  50. alfy says:

    Very good tutorial. I learned a lot!!! Thank you very much for your help.

  51. Ron Mc (Vancouver, Canada) says:

    I am just learning JSF and this was a excellent find for me – answered a lot of questions I have with managed beans. Thanks!

  52. Usman says:

    Hi, Nice Article. Keep up the Good work. Best Regards. Usman@Pakistan

  53. Moez says:

    Is there a way to change a scope of a bean during runtime ?
    What i want to do is depending on a check box that a user can select, the scope should change between view and session .. is this possible ?

    1. max says:

      You can create the bean programatically and place it in any scope this way.

  54. Kumar says:

    Nice post. Appreciate your time and effort.
    Savitha, you are in a wrong field. I bet your resume has got a lot of “creative writing” sections. I would love to take your interview and send you back to the United States of Andhra Pradesh!

  55. Sandeep Pachauri says:

    Great tutorial.. thanks for sharing this

  56. Farkas Istvan says:

    Thank you very much for this tutorial.

  57. Prasad says:

    Have you worked with @ConversationScoped and any chance of a tutorial for that.

  58. Maria says:

    Fantastic post!

  59. RaoPotla says:

    Hi @max, you explained the view scope as follows….”The bean is saved as an attribute of the JSF view. When the JSF view (its state) is saved, the bean is saved as well. When the view is restored, the bean is restored and placed back in request scope.”, is this in JSF2/ Richfaces(a4j:KeepAlive). I read in stackoverflow that viewScoped bean will never be restored to request scope. view scope bean will always operate from the from the bean in the map used for viewScoped beans.

    1. max says:

      Yes, it works like a4j:keepAlive.

Leave a Reply to Ed Burns Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.