Tuesday, 6 July 2010

Simple JSF 2 h:dataTable example using Result for the value attribute

With JSF 2 we can now use a JSTL Result (javax.servlet.jsp.jstl.sql.Result) , well perhaps you could with JSF 1.2 but seemed to be a JSF 2 new feature from what I could see. His a basic example on it. What I like about it is it completely takes the data off the JDBC ResultSet object and lets you work with it independently. Kinda like storing a JDBC ResultSet in an array of Objects but saves you having to define an object and populate it yourself. JSTL Result is easy and only a few lines of code required to use it.

1. Firstly create a basic class which returns a JSTL Result object from a query. In this example the Connection is retrieved from a data source within the container itself.


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package pas.jsf2.fun.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.jsp.jstl.sql.Result;
import javax.servlet.jsp.jstl.sql.ResultSupport;
import javax.sql.DataSource;

/**
*
* @author papicell
*/
public class JdbcUtil
{
private static Connection getJNDIConnection ()
{
Context ctx;
Connection conn = null;

try
{
ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("jdbc/scottDS");
conn = ds.getConnection();

}
catch (Exception ex)
{
Logger.getLogger(JdbcUtil.class.getName()).log(Level.SEVERE, null, ex);
}

return conn;
}

public static Result runQuery (String query, int maxrows) throws SQLException
{
Statement stmt = null;
ResultSet rset = null;
Result res = null;
Connection conn = null;

try
{
conn = getJNDIConnection();
stmt = conn.createStatement();
rset = stmt.executeQuery(query);

/*
* Convert the ResultSet to a
* Result object that can be used with JSTL/JSF tags
*/
if (maxrows == -1)
{
res = ResultSupport.toResult(rset);
}
else
{
res = ResultSupport.toResult(rset, maxrows);
}
}
finally
{
if (rset != null)
{
rset.close();
}

if (stmt != null)
{
stmt.close();
}

if (conn != null)
{
conn.close();
}
}

return res;
}

}

2. Create a Managed Bean as follows.
 
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package pas.jsf2.fun;

import java.sql.ResultSet;
import java.sql.SQLException;
import javax.faces.bean.ManagedBean;
import javax.servlet.jsp.jstl.sql.Result;
import pas.jsf2.fun.jdbc.JdbcUtil;
/**
*
* @author papicell
*/
@ManagedBean(name="JDBCEmpTable")
public class JDBCEmpTable
{
private Result empResultData;

public Result getEmpResultData() throws SQLException
{
populateEmpResultData();
return empResultData;
}

private void populateEmpResultData () throws SQLException
{
empResultData =
JdbcUtil.runQuery("select empno, ename, job from emp", -1);
}

}

3. Finally create the view Facelet page which will display the Result in a h:dataTable component.


<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->

<!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:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>JSTL Result Emp Map Table Demo</title>
</h:head>
<h:body>
<h3 style="font-family: arial; font-variant: small-caps; color: #336699">
JSTL Result Emp Map Table Demo
</h3>
<h:dataTable var="row" value="#{JDBCEmpTable.empResultData}" border="1">
<h:column>
<f:facet name="header">#Empno</f:facet>
#{row.empno}
</h:column>
<h:column>
<f:facet name="header">Name</f:facet>
#{row.ename}
</h:column>
<h:column>
<f:facet name="header">Job</f:facet>
#{row.job}
</h:column>
</h:dataTable>
<p />
<h:link
outcome="index.jsp"
value="Return To Home" />
</h:body>
</html>

4 comments:

D.Wuysan said...

Very nice post on JSF 2.0. Will definitely read the other entries

Anonymous said...

Finally a clean example, thank you.

Anonymous said...

Thank you!

Anonymous said...

Thanks! It is the first example for JSF tables in Inet, which really works! I tryed 3 examples before it, but...
This is great!