As Published In
Oracle Magazine
January/February 2006

Developer JSF


Generating a JSF Data Table

By Deepak Vohra

Use Oracle JDeveloper and JSF to build a data table.

Oracle JDeveloper supports the JavaServer Faces (JSF) standard for building Web-based user interfaces (UIs). Oracle JDeveloper 10g Release 3 (10.1.3) bundles the reference implementation of JSF v1.1, including both the JSF HTML and JSF Core tag libraries. The JSF HTML tag libraries provide new UI components to help developers create Web applications. The JSF data table component represents a data collection in a table.

The article shows you two ways to create a JSF data table within a Web application by using Oracle JDeveloper: using a Web service and using the JSF API. Note that you do not need a Web service to extract database data to populate a JSF data table. Also, the Web service in this example is simplified, but readers will be able to see from the example how a Web service could return a complex datatype to the data table component.

This Web service-based application creates a JSF data table from a static SQL query, using a managed bean. The JSF API application creates a JSF data table from a dynamically generated query.

Initial Setup

For the steps in this article, I installed Oracle Database 10g Release 2 (10.2.0.1.0), specified OracleDB as the instance name running at port 1521, and installed the sample schemas. You also need to install Oracle JDeveloper 10g Release 3 (10.1.3) Early Access 1. In my setup, I installed Oracle JDeveloper on the same machine as the database, and I connected to the database in my scripts by using the Oracle username OE and the password password .

To create the sample data for this article, run the script shown in Listing 1 to create the OE.Catalog table. This script creates a single table with three rows of data that will populate the JSF data table.

Code Listing 1: Catalog.sql 

CREATE TABLE OE.Catalog(CatalogId INTEGER 
PRIMARY KEY, Journal VARCHAR(25), Publisher VARCHAR(25),
 Edition VARCHAR(25), Title Varchar(45), Author Varchar(25));

INSERT INTO OE.Catalog VALUES('1', 'Oracle Magazine', 'Oracle Publishing', 'Nov-Dec 2004', 
'Database Resource Manager', 'Kimberly Floss');
 INSERT INTO OE.Catalog VALUES('2', 'Oracle Magazine', 'Oracle Publishing', 'Nov-Dec 2004', 
'From ADF UIX to JSF', 'Jonas Jacobi');

INSERT INTO OE.Catalog VALUES('3', 'Oracle Magazine', 'Oracle Publishing', 'March-April 2005', 
'Starting with Oracle ADF ', 'Steve Muench');


Part 1: Creating a Data Table, Using a Managed Bean

Let's start by creating a JSF data table by using a managed bean, which represents the data source that will be used in the data table. First, create a new application in Oracle JDeveloper, by choosing File->New->General->Application . Name the application JSFDataTable , and click on OK . In the Create Project dialog box, name your new project DataTable .

Creating a Java bean class and Web service. To build the application, let's start by creating a Java bean class, which will serve as an implementation class for a Web service you will create later. This implementation class consists primarily of getter and setter methods for fields that correspond to the various columns in the database table from which the data table will be generated.

Create the Java bean class, by selecting the DataTable project in Application Navigator and then choosing File->New->General->Java Class . On the Create Java Class screen, specify DataTable as the class name and example.datatable as the package name. Then replace the entire contents of the generated DataTable.java file with the code in Listing 2.

Code Listing 2: DataTable.java 

package example.datatable;

public class DataTable
{
  private int catalogId;
  private String journal;
  private String publisher;
  private String edition;
  private String title;
  private String author;
  
  public DataTable()
  {
  }
  
 public int getCatalogId(){return this.catalogId;}
 public void setCatalogId(int catalogId){this.catalogId=catalogId;}
 public String getJournal(){return this.journal;}
 public void setJournal(String journal){this.journal=journal;}
 public String getPublisher(){return this.publisher;}
 public void setPublisher(String publisher){this.publisher=publisher;}
 public String getEdition(){return this.edition;}
 public void setEdition(String edition){this.edition=edition;}    
 public String getTitle(){return this.title;}
 public void setTitle(String title){this.title=title;}
 public String getAuthor(){return this.author;}
 public void setAuthor(String author){this.author=author;}
 public static void main(String[] args)
  {
    DataTable dataTable = new DataTable();
  }
}


Now that you've created the Web service implementation class, let's create a service endpoint interface (SEI) for the Web service. An SEI for a Web service makes the methods in the Web service implementation class (the bean class) available to a client.

To create the SEI, select the DataTable project and then choose File->New->General->Java Interface . On the Create Java Interface screen, specify MyWebService1SEI as the name and keep the same package name (example.datatable). Now replace the contents of this file with the code in Listing 3.

Code Listing 3: MyWebService1SEI.java 

package example.datatable;

import java.rmi.RemoteException;
public interface MyWebService1SEI extends java.rmi.Remote
{
    public java.lang.String getTitle() throws RemoteException;
    public void setTitle(java.lang.String param0) throws RemoteException;
    public int getCatalogId() throws RemoteException;
    public void setCatalogId(int param0) throws RemoteException;
    public java.lang.String getJournal() throws RemoteException;
    public void setJournal(java.lang.String param0) throws RemoteException;
    public java.lang.String getPublisher() throws RemoteException;
    public void setPublisher(java.lang.String param0) throws RemoteException;
    public java.lang.String getEdition() throws RemoteException;
    public void setEdition(java.lang.String param0) throws RemoteException;
    public java.lang.String getAuthor() throws RemoteException;
    public void setAuthor(java.lang.String param0) throws RemoteException;
}


Next, let's generate a Web service from the Java Bean class. Right-click on the DataTable.java file in Application Navigator, and choose Create J2EE Web Service . In the dialog box that appears, select J2EE 1.4 (JAX-RPC) as the Web service version to create. Note that as Oracle JDeveloper generates the Web service, it adds a WSDL file (MyWebService1.wsdl), a mapping file, and deployment descriptors for the Web service to the project.

Generating the Web service client class. Now that you've created the Web service, let's generate a client class for the Web service. To do so, right-click on the Web service node (MyWebService1.wsdl in the WEB-INF\wsdl directory) and choose Generate Web Service Proxy .

At this point, you may get a warning from Oracle JDeveloper saying that the service endpoint interface created will be shared by the proxy and the Web service. If you were to later modify the Web service, those modifications could change the service endpoint interface and cause compilation errors in the proxy. However, in this example, you won't be modifying the Web service, so you can keep the Web service client class in the same project as the actual Web service. In the warning dialog box, click on Yes to continue.

On the Port Endpoints screen, keep the default setting ("Run Against a service deployed to Embedded OC4J") and click on OK . Oracle JDeveloper then creates a Web service client class file, MyWebService1SoapHttpPortClient.java; adds it to the project; and opens the file in the editor.

Next, let's make two modifications to this Web service client class. First, add an import statement to add the java.sql.* packages. Then add a method called getDataResultSet() to the class. This method returns a ResultSet of data retrieved from the database table you created earlier. Use the code for getDataResultSet() that appears in Listing 4. Note that in the URL string used to create the JDBC connection, I used localhost as my database host name, 1521 as the port number, and OracleDB as the database instance. If your configuration is different, change the values appropriately.

Code Listing 4: getDataResultSet 

public ResultSet getDataResultSet(){
        ResultSet rs=null;

try{
Class.forName("oracle.jdbc.driver.OracleDriver");
String url="jdbc:oracle:thin:@localhost:1521:OracleDB";
Connection connection = DriverManager.getConnection(url, "OE", "password");

Statement stmt=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
ResultSet.CONCUR_READ_ONLY);

rs=stmt.executeQuery("SELECT * FROM OE.CATALOG");
}
 catch(SQLException e){}
 catch(ClassNotFoundException e){}

return rs;
}


Creating the JSP page. Now it's time to create the JSF JSP page. To do so, select the DataTable project in Application Navigator and choose File->New->Web Tier->JSF->JSF JSP . The Create JSF JSP wizard appears.

Click on Next on the intro screen. On the next screen, enter catalog.jsp for File Name, and click on Next . The Component Binding screen appears. Choose "Automatically Bind Components Using a Newly Created Managed Bean"; accept the default values for name, class, and package—as shown in Figure 1; and then click on Next .

 

figure 1
Figure 1: Choosing a component binding style


On the Error Page Options screen, keep the default setting and click on Next . On the Tag Libraries screen, note that the JSF Core 1.0 and JSF HTML 1.0 tag libraries are preselected. Keep these default selections, and click on Next . On the HTML Options screen, keep the default settings and click on Next . Click on Finish on the last screen. Oracle JDeveloper then creates a JSF JSP page, along with a faces-config.xml configuration file and a backing managed bean for the newly created JSF page.

Creating the managed bean. The next step is to create a managed bean from the client class. To do so, double-click on the faces-config.xml configuration file node, in the WEB-INF directory, to open it in the editor. In the editor, select the Overview tab and click on New to add a managed bean, as shown in Figure 2.

 

figure 2
Figure 2: Creating a new managed bean


On the Create Managed Bean screen that appears, specify CatalogBean as the name. For the Class field, click on Browse... , click on the Hierarchy tab, go to the example.datatable package, choose the Web service client class you generated earlier ( MyWebService1SoapHttpPortClient ), and click on OK. Keep Scope set to "request," and click on OK . Oracle JDeveloper creates a new managed bean for the Java bean Web service.

Adding the data table. Next, let's add a data table to the JSF JSP page. In Application Navigator, double-click on catalog.jsp (in the Web Content directory) to open it in the editor. Go to the Component Palette, and select JSF HTML from the drop-down menu. Select the Data Table component to launch the Create Data Table wizard.

Click on Next on the intro screen. On the Binding screen, choose "Bind the Data Table Now" and click on Next .

The Bind Data Table screen appears. The Value field specifies the data collection from which a data table will be generated, the Class field specifies the bean class for the data collection, and the Var field specifies the variable for a row of data in the data collection.

Start by clicking on Bind to bind a data collection to the data table. On the Expression Builder screen that appears, select the dataResultSet variable from the CatalogBean managed bean you generated earlier. Note that the dataResultSet method returns a ResultSet . Add this variable to the Expression frame with the > button, and click on OK to go back to the Bind Data Table screen.

For the Class field, click on the Browse... button, select the DataTable bean class in the example.datatable package, and click on OK . For the Var field, enter catalog as the variable for a row of data in the data collection. With the information entered, the screen looks like the screen in Figure 3. Click on Next .

 

figure 3
Figure 3: Binding the data table


On the "Header and Row Data" screen that appears next, modify the order of the columns so that, from top to bottom, the header values read as follows: Catalog Id, Journal, Publisher, Edition, Title, and Author. Click on Next , and then click on Finish on the Finish screen. The catalog.jsp page, shown in Design view, should now look similar to Figure 4.

 

figure 4
Figure 4: Catalog.jsp data table header values


Finally, right-click on catalog.jsp in the Application Navigator, and choose Run . You've just created a Web application that generates a data table in your default browser, as shown in Figure 5.

 

figure 5
Figure 5: The completed JSF JSP page


Part 2: Creating a Data Table, Using the JSF API

In the previous section, the data table you created was generated from a static query. In this section, you will improve on the application created last time, by generating a data table from a dynamic query specified in the JSF JSP page.

Note that the steps in this example programmatically set the values of the JSF data table component. For this example, it is possible to simply value bind the data table to the ResultSet and use the Oracle JDeveloper 10g Data Table wizard to construct the data table, but the programmatic process in this example can be applied to different types of data and different components.

As in the previous section, let's start by creating an application and a project. This time, name the application DataTable and the project DataTable .

Next, let's add a JSF JSP page to the project. Select the DataTable project in Application Navigator, and then choose File->New->Web Tier->JSF->JSF JSP to start the Create JSP wizard. As you go through the wizard, use the same settings you used in the previous section, entering catalog.jsp as the filename, selecting "Automatically Bind Components Using a Newly Created Managed Bean," and selecting the default options for the other screens.

Next, with the newly created JSP page open in the editor, go to the Component Palette and choose CSS from the drop-down menu. Click on JDeveloper to add the jdeveloper.css file to the page. Back in the editor, click on the first drop-down menu in the upper left corner of the editor and choose Heading 2 . On the page itself, type JSF Data Table as a heading for the JSF JSP page.

Next, in the Component Palette, select JSF HTML from the drop-down menu. Click on the JSP page anywhere under the heading text you just created, to properly position the cursor. Then click on the Input Text component in the Component Palette to add the input text field to the page. Click again on the JSP page to position the cursor below the input text field, and then click on the Command Button component in the Component Palette to add a new button. Now click on the new Command Button , and in the Property Inspector, change the Value property to Data Table . The label on the command button will update to show this new value.

Next, let's add a data table to the JSF JSP page. Start by clicking on the JSF JSP page to position the cursor below the Data Table button. Make sure that JSF HTML is selected in the drop-down list in the Component Palette, and click on the Data Table component. The Create Data Table wizard appears.

Click on Next to get past the intro screen. On the Binding screen, choose "Number of Columns" and specify 6 as the value. This value reflects the number of columns in the database table from which the data table is generated. Click on Finish to exit the wizard. Oracle JDeveloper adds the data table to the page, as shown in Figure 6.

 

figure 6
Figure 6: The JSF JSP page


Next, let's modify the action method of the Data Table button to have it generate a data table when it is clicked. In the editor, double-click on the Data Table button. The source view for Catalog.java, which is the backing bean class for the catalog.jsp page, appears. You need to make two changes to this file. First, add import statements, as shown in Listing 5, to the import section near the top of the page. This code imports java.sql.* classes and Java Server Faces classes needed for the modified action method.

Code Listing 5: Backing bean class import statements 

import java.sql.*;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.model.ResultSetDataModel;


Second, modify the commandButton1_action() method, by pasting in the code shown in Listing 6. Again, note the code near the beginning of the listing for creating the JDBC connection information. Use your actual JDBC connection parameters when adding this code to Catalog.java.

Code Listing 6: Modified commandButton_action method 

ppublic String commandButton1_action()
  {
    // Add event code here...
    
    ResultSet rs;
    try{
Class.forName("oracle.jdbc.driver.OracleDriver");
String url="jdbc:oracle:thin:@localhost:1521:OracleDB";
Connection connection = DriverManager.getConnection(url, "OE", "password");

Statement stmt=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
ResultSet.CONCUR_READ_ONLY);

 rs=stmt.executeQuery((String)inputText1.getValue());

 dataTable1.setBorder(5);
 dataTable1.setCellpadding("1"); 
 dataTable1.setVar("catalog");

HtmlOutputText headerComponent = new HtmlOutputText();
    headerComponent.setValue("CatalogId");
    column1.setHeader(headerComponent);

 headerComponent = new HtmlOutputText();
    headerComponent.setValue("Journal");
    column2.setHeader(headerComponent);

 headerComponent = new HtmlOutputText();
    headerComponent.setValue("Publisher");
    column3.setHeader(headerComponent);

 headerComponent = new HtmlOutputText();
    headerComponent.setValue("Edition");
    column4.setHeader(headerComponent);

 headerComponent = new HtmlOutputText();
    headerComponent.setValue("Title");
    column5.setHeader(headerComponent);

 headerComponent = new HtmlOutputText();
    headerComponent.setValue("Author");
    column6.setHeader(headerComponent);

HtmlOutputText column1Text=new HtmlOutputText();
ValueBinding vb = 
FacesContext.getCurrentInstance().getApplication().createValueBinding("#{catalog.catalogid}");
column1Text.setValueBinding("value", vb);
column1.getChildren().add(column1Text);

HtmlOutputText column2Text=new HtmlOutputText();
 vb = 
FacesContext.getCurrentInstance().getApplication().createValueBinding("#{catalog.journal}");
column2Text.setValueBinding("value", vb);
column2.getChildren().add(column2Text);

HtmlOutputText column3Text=new HtmlOutputText();
 vb = 
FacesContext.getCurrentInstance().getApplication().createValueBinding("#{catalog.publisher}");
column3Text.setValueBinding("value", vb);
column3.getChildren().add(column3Text);

HtmlOutputText column4Text=new HtmlOutputText();
 vb = 
FacesContext.getCurrentInstance().getApplication().createValueBinding("#{catalog.edition}");
column4Text.setValueBinding("value", vb);
column4.getChildren().add(column4Text);

HtmlOutputText column5Text=new HtmlOutputText();
 vb = 
FacesContext.getCurrentInstance().getApplication().createValueBinding("#{catalog.title}");
column5Text.setValueBinding("value", vb);
column5.getChildren().add(column5Text);

HtmlOutputText column6Text=new HtmlOutputText();
 vb = 
FacesContext.getCurrentInstance().getApplication().createValueBinding("#{catalog.author}");
column6Text.setValueBinding("value", vb);
column6.getChildren().add(column6Text);

ResultSetDataModel dataModel=new ResultSetDataModel();
dataModel.setWrappedData(rs);
dataTable1.setValue(dataModel);

}
 catch(SQLException e){}
 catch(ClassNotFoundException e){}

    return null;
  }


Walking through the code. The code in Listing 6 contains all of the logic used to generate a data table. Because it's somewhat long, let's walk through the code to see what it does.

First, obtain a JDBC connection with the database:

 

Class.forName("oracle.jdbc.driver.OracleDriver");
String url="jdbc:oracle:thin:@localhost:1521:OracleDB";
Connection connection = DriverManager.getConnection(url,"OE", "password");


Next, create a Statement to obtain a ResultSet .

 

Statement 
stmt=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
ResultSet.CONCUR_READ_ONLY);


Then query the database with the SQL SELECT statement specified in the Input Text field of the JSF page. 

ResultSet 
rs=stmt.executeQuery((String)inputText1.getValue());


Next, set the border and cell padding on the data table. Then set the variable for a row of data in the ResultSet retrieved from the database.

Next Steps


READ more about JSF
java.sun.com/j2ee/javaserverfaces/reference
oracle.com/technetwork/products/jdev/101/howtos/jsftoplink

DOWNLOAD
Oracle JDeveloper 10g

LEARN about
Oracle Application Development Framework (ADF)

 

dataTable1.setBorder(5);
dataTable1.setCellpadding("1");
dataTable1.setVar("catalog");


Next, set the header values for each column in the data table. Iterate through each of the six columns shown in the data table. For example, the column header for the CatalogId column is set as follows: 

HtmlOutputText headerComponent = new HtmlOutputText();
headerComponent.setValue("CatalogId ");
column1.setHeader(headerComponent);


Next, for each column in the data table, specify a value binding for an HtmlOutputText component and add the component to the column. For the CatalogId column, add an HtmlOutputText component as follows: 

HtmlOutputText column1Text=new HtmlOutputText();
ValueBinding vb = 
FacesContext.getCurrentInstance().getApplication().createValueBinding("#{catalog.catalogid}");
column1Text.setValueBinding("value", vb);
column1.getChildren().add(column1Text);


Next, create a ResultSetDataModel and set the data for this ResultSetDataModel to be the ResultSet retrieved from the SQL query. 

ResultSetDataModel dataModel=new ResultSetDataModel();
dataModel.setWrappedData(rs);


Finally, bind the data table with the ResultSetDataModel

dataTable1.setValue(dataModel);


Running the application. You've finished creating the new JSF JSP application. All that's left to do is to right-click on the new catalog.jsp page in Application Navigator and choose Run to start the application.

A new JSF JSP should appear in your default browser, as shown in Figure 7. In the text field, type SELECT * FROM OE.CATALOG and click on the Data Table button. The application will generate a new data table based on the SQL query you specified.

 

figure 7
Figure 7: The Completed JSF data table application


Conclusion

This article showed you how to develop a JSF JSP application by using some of the UI components provided by the JSF API. As demonstrated, the Create Data Table wizard in Oracle JDeveloper can generate data tables from a static query, specified in the data source class, or from a dynamic query, specified in the JSF JSP page. 


Deepak Vohra (dvohra09@yahoo.com) is a Sun Certified Java Programmer, a NuBean consultant, and has been published in onjava.com, XML Journal, WebLogic Developer's Journal, and OTN.


Send us your comments