Srikanth Technologies

Using AJAX with JSF

In this blog, I show how to use AJAX with JSF. We use SUN RI (Reference Implementation) of JSF with RichFaces of JBOSS. Sun RI is the core implementation of JSF, whereas RichFaces of JBoss is the extension of JSF to provide additional components that support AJAX. RichFaces also provides support for Ajax for existing JSF components. We can provide AJAX support for stanadard JSF components like SelectOneMenu etc.

I show a JSF page that uses two dropdown listboxes where first dropdown list displays titles of jobs taken from JOBS table of HR account in Oracle10g. When user selects a job in the dropdown list then we use AJAX to get names of the employees from EMPLOYEES table. The task of using AJAX is achieved using <a4j:support> element of RichFaces library.

This demo application uses the following software.

Creating a new web project with JSF support

Take the following steps to create a new web application using NetBeans 6.5
  1. Start NetBeans 6.5.
  2. Select File->New Project.
  3. Select Java Web in Categories and select Web Application in Projects.
  4. Enter EmpInfo as the name of the project and specify the folder where you want the project to be created.
  5. Select Apache Tomcat as the server. You can even select Glassfish.
  6. In Frameworks window, select JavaServer Faces as the framework.
  7. Click on Finish.

NetBeans creates a new web application with JSF 1.2 and JSTL libraries included. It also provides required JSF entries in web.xml (configuration of FacesServlet) and faces-config.xml .

Add OJDBC14.JAR, which contains Oracle Driver, to project using Libraries node in Project window.

Adding RichFaces Library To Project

Take the following steps to download and add RichFaces library to your web application in NetBeans.
  1. Download Richfaces from http://www.jboss.org/jbossrichfaces. The latest version as of now is 3.3.0.
  2. Go to download page and select richfaces-ui-3.3.0.GA-bin.zip, which is of 30 MB.
  3. Unzip the zip file to a folder.
  4. Add .jar files found in LIB directory to Web application created in NetBeans using Libraries node in the project window.
  5. In order to use RichFaces, we need to add the following filter configuration to web.xml.
The following is the complete web.xml after filter configuration is added.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <context-param>
        <param-name>com.sun.faces.verifyObjects</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>com.sun.faces.validateXml</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>

    <filter>
        <display-name>RichFaces Filter</display-name>
        <filter-name>richfaces</filter-name>
        <filter-class>org.ajax4jsf.Filter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>richfaces</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>

    <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>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>jobs.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Create JSP and JSF Managed Beans

It is time to create a JSP that displays titles of Jobs taken from JOBS table of HR account in Oracle10g. Once user selects a job in this list then we use tag to make an AJAX call to get names of employees who belong to the job selected by the user. The code for JSP is given below.

jobs.jsp

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%> 
<f:view>
    <h:form>
        <table>
            <tr>
                <td>Select Job :
                <td>
                      <h:selectOneMenu value="#{PayrollBean.jobid}">
                          <f:selectItems value="#{PayrollBean.jobs}"/>
                          <a4j:support event="onchange" reRender="employeesList"/> 
                      </h:selectOneMenu>
                </td>
            </tr>
            <tr>
                <td>Select  Employee : </td>
                <td>
                   <h:selectOneMenu value="#{PayrollBean.empid}"   id="employeesList" >
                            <f:selectItems value="#{PayrollBean.employees}"/>
                   </h:selectOneMenu><br/>
                </td>
            </tr>
        </table>
    </h:form>
</f:view>

The first SelectOneMenu takes items from getJobs() method of PayrollBean. Method getJobs() returns a collection of SelectItem object here jobid is the value and jobtitle is text. It copies the selected jobid into property jobid of PayrollBean.

The most important one in this component is the child tag <a4j:support event="onchange" reRender="employeesList"/>, which is making an AJAX call to server whenever a different option is selected to populate dropdownlist with id employeesList. This is how we provide support for AJAX in the context of JSF. Tag support is taken from a4j library that is provided by RichFaces. JSP uses JSF managed bean called PayrollBean, which is given below.

PayrollBean.java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.faces.model.SelectItem;

public class PayrollBean {
   private String jobid;
   private String empid;

    public String getEmpid() {
        return empid;
    }

    public void setEmpid(String empid) {
        this.empid = empid;
    }

    public String getJobid() {
        return jobid;
    }

    public void setJobid(String jobid) {
        this.jobid = jobid;
        System.out.println(jobid);
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
   private double salary;

   public List<SelectItem> getJobs(){
       ArrayList<SelectItem> jobs = new ArrayList<SelectItem>();
       jobs.add(new SelectItem("0","--- Select Job ---"));
       try {
            Connection con = getConnection();
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery("select job_id,job_title from jobs order by job_title");
            while (rs.next()) {
                jobs.add(  new SelectItem(rs.getString("job_id"),rs.getString("job_title")));
            }
            rs.close();
            st.close();
            con.close();
       }
       catch(Exception ex) {
           System.out.println(ex.getMessage());
       }
       return jobs;
   }

   public List<SelectItem> getEmployees(){
       ArrayList<SelectItem> employees = new ArrayList<SelectItem>();
       employees.add( new SelectItem("0","--Select Employee ---"));

       if ( jobid == null || jobid.equals("0"))
           return employees;
       try {
            Connection con = getConnection();
            PreparedStatement ps = con.prepareStatement("select employee_id, first_name from employees where job_id = ?");
            ps.setString(1,jobid);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                employees.add(new SelectItem(rs.getString("employee_id"),rs.getString("first_name")));
            }
            rs.close();
            ps.close();
            con.close();
       }
       catch(Exception ex) {
           System.out.println(ex.getMessage());
       }
       return employees;
   }
   public Connection getConnection() throws Exception {
       Class.forName("oracle.jdbc.driver.OracleDriver");
       Connection con  = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
       return con;
   }
}
The entry related to the above Managed Bean in Faces-config is as follows:

faces-config.xml

  <managed-bean>
        <managed-bean-name>PayrollBean</managed-bean-name>
        <managed-bean-class>PayrollBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>

Build the project and deploy to Apache tomcat. Running jobs.jsp displays the list of jobs. Select a job to get the list of employees.