Friday, April 19, 2013

Moving on, using a managed bean

So let's try using what is known as JSF managed beans.  Managed beans are plain old Java objects (POJO) that get managed by the JSF controller.

How it technically works is that the JSF library will scan the classes in your project for the @ManagedBean annotation.  When it finds a class, it registers it as a managed type.

Once registered, you can create beans all over the place in your JSF pages.  Beans can have one of six scopes:

  • @RequestScope - This means the bean is created for the life of the HTTP request.  Once the HTTP request has been fully processed the bean is destroyed.  Basically, these beans exist so long as the request for a web page lasts.  Once the page has been serviced, the bean is no longer available.  This also applies to AJAX requests.
  • @SessionScope - This bean is created for the life of the HTTP session.  Once a HTTP session is started, the JSF library will create this bean and allow it to last so long as the HTTP session is still open.  Once the HTTP session ends, due to inactivity or closing the web page, the bean is destroyed.
  • @ViewScope - This is an interesting bean that will last through requests, so long as the current view has not changed.  This is useful is you present a single view to the user and then do a lot of AJAX in the background to modify that view.
  • @ApplicationScope - This is a bean that is created as soon as the application is started.  That means as soon as you publish it to the server or upon the first HTTP packet to the application (this is dictated by the eager=true flag, setting to true is as soon as you publish it.)  Only use this kind of bean for things that can safely be shared between instances of sessions.  Just FYI, don't assume that this automatically means thread safety.
  • @NoneScope - This is a bean that is created as soon as it is requested in a JSF page and destroyed as soon as it was created.  If you use the bean three times in your JSF page, then the bean is created and destroyed three times.  In my example to follow, the none scope would have sufficed.  Use this kind of bean for one shot stuff that doesn't need to be remembered, or if you intend on using this bean within another bean.
  • @CustomScope - This is exactly what it says.  You define when and where the bean exists and get destroyed by modifying a Map that is created for managing this bean.  When you add an entry to the Map, the bean is created, when you remove the entry the bean is destroyed.  Use this when nothing above seems to fit your use-case.
So let's create a bean!

Right mouse click on your project and select New » Other…

This screen appears
 Choose the JSF Managed Bean and click Next >

We're just going to go with the defaults here with a little bit of extra like package name, generally you are going to name this something actually useful.
Fill in the information about your bean and I'm going to set it to request scope.  The package will be lan.testing.  You can also add a little description to the bean.  No idea where this description gets saved at the moment.  Go ahead and click finish.

Now you will have a newly minted request bean.

New JSF Managed Bean
Now at the moment this bean does absolutely nothing other than suck memory.  So let's make it do something more interesting.  Let's add a field in the Java class called message.  We will make this field private.  So let's add that now.  While we are at it, let's set the fields default value by placing that in the constructor.

Adding a field to the bean

Now let's expose that bean so that it can be used on our pages.  We do that by creating standard getters and setters.  Just press Alt+Insert in the IDE to get a popup.

Select the Getter and Setter… option
Check the boxes of the fields you want to expose, since we have one, we are exposing them all.
Your Java class should look like the following:

Your field is now exposed by the bean.
Now that we have exposed the field, let's go ahead and add that to our JSF page.  To access JSF managed beans we need to replace the static text in our tag with #{}.  The pound sign and curly brackets indicate to the JSF libraries that it needs to look at all of the registered classes.

Once we type that into the value you'll notice a code completion pop-up appear.

Code completions is happening.
In the completion box you should see the name of your managed bean.  Go ahead and select it.  It will now appear as #{whateverYouNamedYourBean}.

Go ahead and type period to get the next bit, this will show you what has been exposed by this bean.

Our field exposed by the bean
Go ahead and select the exposed message field.

Our completed code
Once you have done that, go ahead and press the giant play button to see the results.

Ta-da!  Your field in the Java class is now exposed and being used by the JSF libraries.  Right now, not very useful, but good to know that it is working.  All of this on Tomcat!

Quick point:
Beans are meant to allow you to create useful components to be used in your JSF application.  Right now it might be a bit hard to see that, but eventually you'll start building beans that are for all kinds of purposes, with all kinds of different scopes.

The thing to remember about beans is that you should take the million little cogs approach with them.  As opposed to building one giant bean or one huge session bean and one huge request bean, beans should be for a specific purpose in your web application.  You may have one that hold the current user's profile information, another to hold the current conversation that they are in, and so on.

Right now we are only using the read function (get) of the bean.  I'll show you next how to write (set) to the bean and explain a bit about why it works.

No comments: