JSF Managed Beans Example
In this example we will talk about the basics of the JSF Standard and the Managed Bean concept. With these tools we can develop and support an application’s clear architecture, and get an easily integration with java EE modern technologies. Then, we learn how to work with the backend, using JSF Managed Beans.
1. What is JSF 2.x?
JSF 2.0, 2.1 or 2.2 are the new releases of the Java Server Faces (consider it like a standard and a framework of development). Those improve the development cycle of java web-based applications, applying the Contexts and Dependency Injection (CDI), Model-View-Controller (MVC) architecture and Inversion of control (IoC) . They also include various features that make it a robust framework for java web applications. Well, JSF 2.x is the evolution of JSF 1.x that help us to easily integrate with new technologies like Ajax, Restful, HTML5, new servers like Glassfish 4, Wildfly (the old JBoss) and the last JDK Java EE 7 and 8.
2. Why use JSF 2.x?
There are many improvements and advantages regarding its previous version, here are some:
- It’s the official Java EE Web Application Library
- The configuration fully supports annotations, instead of heavy xml description.
- Full support to ajax
- New GUI components, named Facelets instead of old JSP pages.
- More view scopes and improved component’s life cycle
- Support to the new Java EE Servers
3. What is a Managed Bean?
It’s a lightweight Java Bean that is registrered with the framework, to contain the Backend data, and that may contain business logic. Which are the properties of a JSF 2.2 Managed Bean?
- Has the annotation @ManagedBean
- Has a zero-arg constructor
- Has a setter and getter public methods, for their private instance variables
4. What we need to start?
As with every java web application, we need a JSF implementation (Oracle Mojarra, Apache MyFaces), Java EE Server and our main IDE. So, for this example we use:
- JSF 2.2.9 (Mojarra version, we recommend them)
- Apache Tomcat 7
- Eclipse Luna IDE
- JDK 1.7.0_67
5. Step By Step
5.1 Create a Dynamic Web Project
First download the JSF 2.2 Mojarra here, then create a new Dynamic Web Project, and add the JSF Library. Our project must look like these:
5.2 Configure Java EE Project
In a Java EE Web Application, we have to consider some fundamental concepts that we will explain shortly.
The compatibility between Servlet API, JDK, JSF and Server supported versions, in this example we used Servlet 3.0 that’s compatible with Tomcat 7 or later. As the JSF version is 2.2 requires a JDK 1.7 or above, if you look the project facets may have this configuration:
5.3 Configuration Files
In the example we develop a Fibonacci Series Calculator, that based on the number that the user enters we get the value in the F-Series.
Let’s Get Started!
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>JSFManagedBeansExample</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <context-param> <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <context-param> <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name> <param-value>resources.application</param-value> </context-param> <listener> <listener-class>com.sun.faces.config.ConfigureListener</listener-class> </listener> </web-app>
The configuration file web.xml
is the starting point to load all the dependencies of a java web application. Tomcat Server starts looking for this file and process tag by tag of the xml file. We look into the tags:
- welcome-file: The first view to render when application starts
- servlet: The Faces Servlet it’s the ‘heart’ of JSF, and process every request of the application.
- servlet-mapping: Define the url patterns that the Faces Servlet is involved.
- context-param: Define some JSF parameters
- listener: Parse all relevant JavaServer Faces configuration resources, and configure the Reference Implementation runtime environment
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd" version="2.2"> </faces-config>
The faces-config file is no needed because everything is automatic configured for the JSF framework based on Java Annotations.
5.4 JSF Pages
Now, we create the views, index.html (Simple html page) and fibonacci.xhtml (Facelets View).
index.html
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <meta http-equiv="REFRESH" content="2; url=http://localhost:8080/JSFManagedBeansExample/fibonacci.jsf" /> <title>JSF Managed Beans JCG Example</title> </head> <body> <p>This is the home page, will we redirected in 2 seconds to the Managed Beans Example.</p> </body> </html>
fibonacci.xhtml
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>JSF Managed Beans JCG Example</title> </h:head> <h:body> <f:view> <h2>Get The N Fibonacci Number</h2> <p> <h:form id="fibonnaci"> Number of the Fibonnaci Series: <h:inputText id="number" value="#{managedBeanController.numFibonacci}" /> <h:commandButton action="#{managedBeanController.performFibonnaciOperation}" value="Calculate"> </h:commandButton> <br /> Result: <h:outputText id="result" value="#{managedBeanController.result}" /> <h:messages infoStyle="color: blue" globalOnly="true" /> </h:form> </p> </f:view> </h:body> </html>
The first page, it’s a simple HTML view, you can combine both technologies (HTML5 + JSF2.2) and develop powerfull applications, this view only redirects to a view that’s processed by Faces Servlet, instead of html isn’t processed. How do that? in the 7 line, with the code meta http-equiv="REFRESH" content="2; url=http://localhost:8080/JSFManagedBeansExample/fibonacci.jsf"
.
The second page, it’s a facelets view. What are the differences with HTML? The facelets imports a set of tags allocated in the namespaces defined in the 4 and 5 line, with this get a lot of features that the normal HTML doesn’t has. Look at the view, line by line. With the namespaces abbreviated in H and F we can use the component f:view
that wrap all the GUI, then, a form with the data that will be send to the Managed Bean. The h:inputText
set the number in the numFibonacci
variable of managedBeanController
, the commandButton
executes the business operation set in the action
property, and the last outputText
component shows the result of the operation.
5.5 Java Managed Bean
ManagedBeanController.java
package com.javacodegeeks.jsf.beans; import java.io.Serializable; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.context.FacesContext; import javax.faces.event.AjaxBehaviorEvent; /** * @author Andres.Cespedes * @version 1.0 $Date: 07/02/2015 * @since 1.7 * */ @ManagedBean(name = "managedBeanController") @SessionScoped public class ManagedBeanController implements Serializable { private int numFibonacci; private long result; /** * Number for serialization */ private static final long serialVersionUID = 8150756503956053844L; /** * No-arg constructor */ public ManagedBeanController() { numFibonacci = 0; result = 0; } /** * @return the numFibonacci */ public int getNumFibonacci() { return numFibonacci; } /** * @param numFibonacci * the numFibonacci to set */ public void setNumFibonacci(int numFibonacci) { this.numFibonacci = numFibonacci; } /** * @return the result */ public long getResult() { return result; } /** * @param result * the result to set */ public void setResult(long result) { this.result = result; } /** * Business Operation to get the Fibonnaci N-number * * @param param * @return */ private long getFibonnaciNumber(int param) { if (param == 1 || param == 2) { return 1; } long actual = 1; long next = 1; long sum = 0; for (int i = 2; i < param; i++) { sum = next + actual; actual = next; next = sum; } return next; } /** * Non ajax perform Fibonacci Operation */ public void performFibonnaciOperation() { if (numFibonacci <= 0) { setResult(0L); } else { setResult(getFibonnaciNumber(numFibonacci)); } FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Fibonacci Calculation for the " + numFibonacci + " number was: " + result, "Fibonacci Calculation"); FacesContext.getCurrentInstance().addMessage(null, facesMsg); } /** * Ajax perform Fibonacci Operation * * @param event */ public void ajaxPerformFibonnaciOperation(final AjaxBehaviorEvent event) { if (numFibonacci <= 0) { setResult(0L); } else { setResult(getFibonnaciNumber(numFibonacci)); } FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Fibonacci Calculation for the " + numFibonacci + " number was: " + result, "Fibonacci Calculation"); FacesContext.getCurrentInstance().addMessage(null, facesMsg); } }
The example is very simple, so we will only review the most important aspects. Every managed bean must be registered with the @ManagedBean
annotation, we explicitly define a name for the bean, but by default it’s the same name with the first letter in lowercase. The scope, you can give a scoped life-time to the ManagedBean depending on your need, may be of any types, here we use @SessionScoped to do the bean lives as long as the HTTP session lives. The ajaxPerformFibonnaciOperation
has a AjaxBehaviorEvent
parameter, that is mandatory for every ajax method in jsf.
To invoke an ajax method in the form, we change the commandButton definition to:
<h:commandButton value="Calculate"> <f:ajax execute="@form" render="@all" listener="#{managedBeanController.ajaxPerformFibonnaciOperation}" /> </h:commandButton>
There are 3 important attributes to look, execute
, to execute the form; render
, to update all the components, and listener
to execute the ajax operation.
5.6 Running the Example
Let’s make the project run on the Tomcat Server.
5.7 Key Points
Tips
- Check the compatibility between JSF and every tool that has been used
- Only register each ManagedBean with XML descriptor or Annotations, but never with both!
- Check the JSF properties and customize your application with them, through the
context-param
tag. - Always wrap all the GUI components with
view
element. - ManagedBeans names are case sensitive, check the names carefully.
6. Download the Eclipse Project
You can download the full source code of this example here: JSFManagedBeansExample