☰ See All Chapters |
JSF Managed Bean
Managed beans are the conduits between the user interface and the backend of the application (FacesServlet). A Java bean is a class (should be POJO) that exposes properties and events to an environment such as JSF. A property is any attribute of a bean that has
A name
A type
Methods for getting and/or setting the property value
It should be Serializable (should implement Serializable Interface)
It must have a public default constructor - that is, a constructor without parameters.
All properties should be declared private.
All properties should have public getter and setter methods.
When the page is displayed, the framework calls the getter method to obtain the current property value. When the page is submitted, the framework invokes the setter methods to set the value that the user entered.
According to the bean specification, it is legal to omit a read or write method. For example, if getPassword is omitted, then password is a write-only property. That might indeed be desirable for security reasons. However, JSF deals poorly with this situation and throws an exception instead of taking a default action when a read or write method is absent. Therefore, it is best to give read/write access to all bean properties.
You may wonder where the term “bean” comes from. Well, Java is a synonym for coffee (at least in the United States), and coffee is made from beans that encapsulate its flavor. You may find the analogy cute or annoying, but the term has stuck.
In a JSF application, beans are commonly used for the following purposes:
User interface components (traditional user interface beans)
Tying together the behavior of a web form (called “backing beans”)
Business objects whose properties are displayed on web pages(like displaying list of cities, a data table having many data in rows and columns)
Services such as external data sources that need to be configured when an application is assembled
ManagedBean can have a public method with no parameters and returns an object which will be passed to navigation hander when <h:commandButton>/<h:commandLink> is pressed.
Managed bean example
package com.java4coding;
public class HelloBean {
private String name; private String password;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }
public String checkUser() { String str = null; if (name.equalsIgnoreCase("Manu_M") && password.equalsIgnoreCase("mm")) { str = "success"; return str; } else { str = "failure"; return str; } } } |
Backing Beans
Assume we created one custom UI Component, and tag handling class for this UI component is as below
Class UIOutput{ … … } |
Now how to use this custom tag in facelets, when user uses this component in UI, object of the tag handling class will be created. Now where to store this object, when response is given back to user, this custom tag should be displayed based on how user used that custom tag earlier.
So one way to use this tag is we bind this UI component (Custom tag) to some property in some java class, and such properties will store the objects of custom UI components, such a java class is called BackingBean.
Backing beans are JavaBeans components associated with UI components used in a page. Backing-bean management separates the definition of UI component objects from objects that perform application-specific processing and hold data. The backing bean defines properties and handling-logics associated with the UI components used on the page. Each backing-bean property is bound to either a component instance or its value. A backing bean also defines a set of methods that perform functions for the component, such as validating the component's data, handling events that the component fires and performing processing associated with navigation when the component activates.
public class CutomTagClass { private UIOutput mycomponent;
public UIOutput getMycomponent() { return mycomponent; }
public void setMycomponent(UIOutput mycomponent) { mycomponent = this.mycomponent; }
... ... } |
In facelet we use this Custom UI component as below
<!DOCTYPE … … > <html xmlns="https://www.w3.org/1999/xhtml" xmlns:h="https://xmlns.jcp.org/jsf/html" xmlns:f=https://xmlns.jcp.org/jsf/core xmlns:prefix=”location where tag handler class is present” > <h:body > <prefix:tagName binding= "#{BackingBeanName.MethodName}"………> </prefix:tagName> </h:body> </html> |
For tag UIOutput we can write facelet like below
ManagedBean is a type of BackingBean. ManagedBean can be a BackingBean, but BackingBean cannot be ManagedBean. 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.
What is the difference between a Backing Bean and Managed Bean?
Backing Beans | Managed Beans |
Any bean referenced by a form is a backing bean. | Managed bean is either registered with JSF either in faces-config.xml or annotated with @ManagedBaean annotation. These beans are automatically instantiated and initiated by JSF. |
Backing Beans should be defined only in the request scope. | Managed beans instantiated by JSF can have request, session or application scope. |
Managed bean scopes
JSF2 offers six predefined scopes for Managed Bean. Scope can be set in faces-config.xml file. Scope lifetime and use are described in detail below:
request Scope : a bean in this scope lives as long as the HTTP request-response lives. It get created upon a HTTP request and get destroyed when the HTTP response associated with the HTTP request is finished (this also applies to ajax requests!). JSF stores the bean as an attribute of HttpServletRequest with the managed bean name as key. It is also available by ExternalContext#getRequestMap(). Use this scope for pure request-scoped data. For example, plain vanilla GET requests which should present some dynamic data to the enduser depending on the parameters. You can also use this scope for simple non-ajax forms which do not require any model state during processing.
view Scope : a bean in this scope lives as long as you're interacting with the same JSF view in the browser window/tab. It get created upon a HTTP request and get destroyed once you postback to a different view. It doesn't immediately get destroyed when you leave/close the view by a GET request, but it is not accessible the usual way anymore. JSF stores the bean in the UIViewRoot#getViewMap() with the managed bean name as key, which is in turn stored in the session. You need to return null or void from action (listener) methods to keep the bean alive. Use this scope for more complex forms which use ajax, data tables and/or several rendered/disabled attributes whose state needs to be retained in the subsequent requests within the same browser window/tab (view).
session Scoped : a bean in this scope lives as long as the HTTP session lives. It get created upon the first HTTP request involving this bean in the session and get destroyed when the HTTP session is invalidated (or when you manually remove the bean from the session map). JSF stores the bean as an attribute of HttpSession with the managed bean name as key. It is also available by ExternalContext#getSessionMap(). Use this scope for pure session-scoped data which can safely be shared among all browser windows/tabs (views) within the same session. For example, the logged-in user, the user preferences such as user-specific settings and the chosen language/locale, etc.
application Scope : a bean in this scope lives as long as the web application lives. It get created upon the first HTTP request involving this bean in the application (or when the web application starts up and the eager=true attribute is set in @ManagedBean) and get destroyed when the web application shuts down (or when you manually remove the bean from the application map). JSF stores the bean as an attribute of the ServletContext with the managed bean name as key. It is also available by ExternalContext#getApplicationMap(). Use this scope for pure application-scoped data which can safely be shared among all sessions. For example, constants such as country codes, static dropdown values, web application specific settings, etc.
none Scope : a bean in this scope lives as long as a single EL evaluation. It get created upon an EL evaluation and get destroyed immediately after the EL evaluation. JSF does not store the bean anywhere. So if you have for example three#{bean.someProperty} expressions in your view, then the bean get effectively created three times. Use this scope for a data bean which is purely supposed to be injected in another bean of a defined scope. The injected bean will then live as long as the acceptor bean.
Custom Scope : a bean in this scope lives as long as the bean's entry in the custom Map which is created for this scope lives. You need to create and prepare this Map yourself in a broader scope, for example the session scope. You need to control the removal of the bean from the Map yourself. Use this scope if no one of the other scopes suits the requirement, for example a conservation scope which spans across multiple views.
All Chapters