Anda di halaman 1dari 16

30 juni 2008

Data Binding: from JSP to JSF


Ren van Wijk

Transfer Solutions 2008 www.transfer-solutions.com
1
Data Binding: from JSP to JSF
Ren van Wijk
DATA BINDING: FROM JSP TO JSF
Ren van Wijk, Transfer Solutions BV
ABSTRACT
Data shared between web components, either servlets or pages created using JavaServer Pages (JSP) or JavaServer Faces
(JSF) technology, is usually maintained in a database. How the data sharing, i.e. data binding, for the different technologies
can be accomplished is discussed by using examples. The examples use the MVC architecture, i.e., the applications are
divided into three layers: model, view and controller.
Introduction
This paper is restricted to presentation-oriented web applications, i.e., interactive web pages containing various types of
markup language and dynamic content in response to requests. Web components, such as servlets and JSPs, provide the
dynamic capabilities. Interaction between a web client and a web application can, in short, be described as: web components,
on the server, receive a request from a client and generate a response based on that request.
Since the introduction of servlets and JSP technology, additional technologies have been developed.
Figure 1. Web application technologies.
Note that servlets are the foundation. Though, they are not discussed, every technology is translated into servlets and then
compiled. The depicted layers of the MVC architecture can be defined as:
Model layer - Contains the data for the current page.
View layer - Contains the pages for the user interface which are used to view and/or modify the data.
Controller layer - Processes the input and determines the page navigation.
In addition to the described layers, ADF adds an additional layer, i.e.,
Business Services Layer - Accesses data from a database and encapsulates business logic.
Data shared between web components is usually maintained in a database. To elaborate on the data sharing, i.e. data binding,
for the different technologies, three examples are discussed:
The first example uses JSP technology. In this example, JDBC is used to obtain data from the database. To access
the obtained data as Java objects, JavaBeans components are used. Recurring tasks are encapsulated in custom tags.
By using such tags the design of the web user interface is simplified. To this end, jMaki components are also
discussed.
Subsequently, an example using JSF is given. JSF builds on servlets and JSP, and provides a user interface
component framework by introducing web components that have attributes and events. Hibernate is used to obtain
data from the database and map it to Java classes. The JSF page is build using Trinidad components.
Finally, an example is given which uses ADF (BC4J and ADF Faces).
Data model
The following data model is used.
Java Servlets
JavaServer Pages
JavaServer
Faces
JSP Standard
Tag Library
Java Servlets
JavaServer Pages
JavaServer
Faces
JSP Standard
Tag Library
ADF
Business
Services
Model
Controller
View
Architecture
ADF
Business
Services
Model
Controller
View
Architecture

Transfer Solutions 2008 www.transfer-solutions.com
2
Data Binding: from JSP to JSF
Ren van Wijk
Figure 2. Data model.
JavaServer Pages (JSP)
A JSP page is a text document that contains two types of text: static data, which can be expressed in any text-based format,
and JSP elements, which construct dynamic content. To access the data from the database JDBC is used. Queried data is
added to List of Beans objects in order to gain easy access to the data by means of Java objects. JSP technology also provides
a mechanism for encapsulating recurring tasks in custom tags. By using such tags the design of the web user interface is
simplified. To this end, the use of jMaki is also discussed.
Figure 3. Application architecture.
To distribute the functionality and minimize the dependencies between different application objects a model-view-controller
architecture is used, i.e.,
Model layer - Contains business data and governs the rules to access and modify that data.
View layer - Obtains the data from the model and specifies how the data is presented.
Controller layer - Defines the overall behavior of the application and selects the next view given the user's
interaction.
The model layer consists of a Java class DepartmentData containing JDBC statements, for example,
public List getDepartmentData() {
String selectQuery = "select deptno, dname, loc from dept";
List data = new ArrayList();
try {
PreparedStatement select = ConnectionDatabase.getConnecion().prepareStatement(selectQuery);
ResultSet rs = select.executeQuery();
DepartmentBean db = null;
while (rs.next()) {
db = new DepartmentBean();
db.setDepartmentNumber(rs.getString("deptno"));
db.setDepartmentName(rs.getString("dname"));
db.setLocation(rs.getString("loc"));
data.add(db);
}
select.close();
rs.close();
View
Controller
Model
DepartmentHelper
DepartmentData
JDBC
View
Controller
Model
DepartmentHelper
DepartmentData
JDBC

Transfer Solutions 2008 www.transfer-solutions.com
3
Data Binding: from JSP to JSF
Ren van Wijk
} catch (SQLException ex) {
ex.printStackTrace();
}
return data;
}

The code executes a query and puts the results into a List of Beans object. In order to use this concept, the JavaBeans design
conventions must be obeyed, i.e.,
Access properties through public methods
o Read properties: PropertyClass getProperty() {...}.
o Write properties: setProperty(PropertyClass pc) {...}.
No arguments constructor
For example,
public class DepartmentBean {

private String departmentNumber;
private String departmentName;
private String location;

public DepartmentBean() {
}

public void setDepartmentNumber(String departmentNumber) {
this.departmentNumber = departmentNumber;
}

public String getDepartmentNumber() {
return departmentNumber;
}
accessors for the remaining fields.
}

The controller layer consists of a Java class, called DepartmentHelper, which handles the page logic, for example,
public class DepartmentHelper {

private String tableForDepartmentData = null;
private String postData = null;

public DepartmentHelper() {
}

public String getTableForDepartmentData(){
generateHTMLTable();
}

public String getPostData() {
return postData;
}

public void setPostData(String postData) {
this.postData = postData;
}
}

Note that this class also obeys the JavaBeans conventions. The choice for this design lies in accessing various methods,
contained in the class, by using expression language (EL). To use a JavaBeans component on a page the element
jsp:useBean must be used, for example
<jsp:useBean id="department" class="userinterface.department.DepartmentHelper" scope="session">
<jsp:setProperty property="postData" name="department" value="departments.jsp"/>
</jsp:useBean>

The JavaBeans component is accessible in the defined scope, in this case the session scope. The value of the attribute id
determines the identifier and the name of the bean in the scope. The value of the attribute class must contain the fully
specified class name. To reference a property on a page, for example tableForDepartmentData,
<jsp:getProperty name="department" property="tableForColumnData"/>

can be used. This invokes the getTableForDepartmentData() method, from the JavaBeans component DepartmentHelper,
which generates an HTML form containing a table, edit links for each row in the table, and a button to add new data. The

Transfer Solutions 2008 www.transfer-solutions.com
4
Data Binding: from JSP to JSF
Ren van Wijk
data for the table is obtained from the method getDepartmentData() of the class DepartmentData which resides in the model
layer.
JavaServer Pages Standard Tag Library (JSTL)
JSTL contains basic functionality common for JSP applications. For example, to achieve a certain flow control, JSTL
provides easy to use tags to accomplish this, i.e.,
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
...
</head>
<body>
<jsp:useBean id="department" class="userinterface.department.DepartmentHelper" scope="session">
<jsp:setProperty property="postData" name="department" value="departments.jsp"/>
</jsp:useBean>
<c:choose>
<c:when test="${department.renderInsert}">
HTML voor insert
</c:when>
<c:when test="${department.renderUpdate}">
HTML voor update
</c:when>
<c:otherwise>
<jsp:getProperty name="department" property="tableForColumnData"/>
</c:otherwise>
</c:choose>
</body>
</html>

Note the addition of the directive taglib, which indicates the use of an extra library. In the example above, a <c:choose> tag
is used to test for certain user input. To be more specific if the user clicks the 'add' button an insert form is rendered, if an
'edit' link is clicked the corresponding row is rendered as an insert form. Default a table containing the data is shown. The
different test statements are evaluated by using expression language (EL). The DepartmentHelper properties renderInsert
and renderUpdate are of the boolean type. For example, if the user clicks the 'add' button a value is bound to a request
parameter 'insert',
<form method="post" action="departments.jsp">
<input name="insert" type="submit" value="add"/>
</form>

This parameter is passed to the JavaBeans property insertButton,
<jsp:setProperty name="department" property="insertButton" value="${param.insert}"/>

after which the EL expression ${department.renderInsert} is evaluated by the method isRenderInsert(), which returns a
boolean.
Custom tags
Custom tags are user defined JSP elements. To use custom tags (or any other tag library for that matter) a taglib directive
must be added to the page,
<%@ taglib uri="/WEB-INF/CustomTags.tld" prefix="CustomTags"%>

The attribute prefix defines the prefix, which distinguishes one tag library from the other. The attribute uri refers to URI of
the tag library descriptor (TLD). This defines the unique identifier for the library.
A JSP page is processed from top to bottom. Tags bound to a tag library issue an event. This event invokes the method
doStartTag() of the TagSupport class. By inheriting from TagSupport and overriding the method doStartTag() custom
code and functionality can be associated with an event. Finally, the closing tag is reached and the method doEndTag() is
invoked. For example, the methods can be overridden as,
public class MenuTag extends TagSupport {

public int doStartTag() {
JspWriter out = pageContext.getOut();
try {
MenuHandler mh = new MenuHandler();
out.append(mh.getMenu());
} catch (IOException ioe) {
System.out.println("Error in MenuTag: " + ioe);
}
return EVAL_BODY_INCLUDE;
}

Transfer Solutions 2008 www.transfer-solutions.com
5
Data Binding: from JSP to JSF
Ren van Wijk

public int doEndTag() {
return EVAL_PAGE;
}
}

The method getMenu(), invoked in doStartTag(), generates HTML output which represents a hierarchical menu structure,
i.e., it recurses through the data structure of the table MODULES, which has a self referencing foreign key.
The, before mentioned, TLD is an XML document containing information about the library as a whole and each occurring
tag within the library. A TLD must have the extension .tld and be located in the directory /WEB-INF/. For example, the tag
menu can be defined as,
<taglib >
<display-name>CustomTags</display-name>
<tlib-version>1.0</tlib-version>
<short-name>CustomTags</short-name>
<uri>/webapp/CustomTags</uri>
<tag>
<name>menu</name>
<tag-class>userinterface.tags.menu.MenuTag</tag-class>
<body-content>JSP</body-content>
</tag>
</taglib>

To reference the tag on a page the element <CustomTags:menu/> must be used.
jMaki
jMaki is a lightweight framework for creating web 2.0 applications using built-in templates, a model for creating and using
Ajax-enabled widgets, and a set of services to tie the widgets together and enable them to communicate with external
services.
A typical jMaki widget consists of the following resources:
component.js - Contains the JavaScript code used to wrap the widget, handles user-initiated events generated by the
widget, and interacts with the Ajax mechanism.
component.htm - An HTML file that the rendering mechanism will use as a template to render the widgets to the
client.
component.css - A CSS style sheet that controls the appearance of the widget.
widget.json - A JavaScript file in JavaScript Object Notation (JSON) format that describes the usage of the widget's
attributes and the format of data that it accepts.
To use jMaki widgets in an application, include the widgets components described above as well as some additional
resources:
jmaki.js - Contains the JavaScript utilities that manage loading jMaki widgets on the client.
config.json - Contains configuration information for third party libraries including the location, application keys, and
global styles associated with a specific library that a widget might use.
glue.js, system-glue.js - Used to "glue" widgets together. These files are used to register and define widget event
listeners, to publish events to a topic, and to provide the means for a widget to subscribe to a topic.
ajax-wrapper-comp.jar - Contains the server runtime code that renders the template code and resource links using
information in the config.json file.
org-json-0.0.1.jar - Marshalling and unmarshalling of data in JSON format.
To add a jMaki widget to a page,
add the widget's resources to the application,
add the jMaki tag library to the page,
add a custom jMaki tag that references the widget,
for example,
<%@ taglib prefix="a" uri="http://jmaki/v1.0/jsp" %>
<jsp:useBean id="bean" scope="session" class="userinterface.jmaki.JMakiHelper"/>
<a:widget name="dojo.table"
value="{columns : [

Transfer Solutions 2008 www.transfer-solutions.com
6
Data Binding: from JSP to JSF
Ren van Wijk
{ label : 'Name', id : 'name'},
{ label : 'Address', id : 'completeaddress'},
{ label : 'Zip', id : 'zip'},
{ label : 'Phone', id : 'phone'},
{ label : 'Creditlimit', id : 'creditlimit'}
],
rows : ${bean.customerData}}"/>
<a:widget name="google.map"
args="{centerLat:52, zoom:8, width:450, height:300, mapType:'REGULAR', centerLon:5}" />

This adds a table and Google map to the page.
Data can be passed to the table in JSON format. The table uses the following format,
/*
* tabledata ::= "{" <columns> [<rows>] "}"
* columns ::= "[" {<column>} "]"
* column ::= "{ label :" <string>" "id :" <columnid> "},"
* columnid :: = <string>,
* rows :: = "[" {<row>} "]"
* row ::= "{" [< rowId >] , <columnid> ": " [<string> | <object>]"}",
* rowId :: = "rowId :" "<string>"
* object :: = "object :" "<JavaScript Object Literal>"
*/

This says that the table consists of columns and rows. A column has a label and an id. In the example, the ids are already
entered in the page. The rows references a JavaBeans component through the EL expression ${bean.customerData}. This
expression invokes the method getCustomerData, which looks as follows,
public String getCustomerData() {
JSONArray customers = new JSONArray();
JSONObject customerRow = new JSONObject();
List data = jmakiData.getPersonInfo();
Iterator iterator = data.iterator();
while (iterator.hasNext()) {
CustomerBean cb = (CustomerBean)iterator.next();
try {
customerRow.put("name", cb.getName());
customerRow.put("completeaddress",
"<a class=\"link\" href=\"javascript:jmaki.publish('/jmaki/mapLocation','" +
cb.getAddress() + "');\">" + cb.getAddress() + "</a>");
} catch (JSONException ex) {
ex.printStackTrace();
}
customers.put(customerRow);
customerRow = new JSONObject();
}
return customers.toString();
}

A row (customerRow) is created by using the column ids defined in the table component on the page, and bind these ids to a
certain piece of data. This row, in turn, is then added to a collection of rows (customers). The JSON API is used to perform
the data conversion.
The example also adds a publisher in the form of a link to the application, i.e.,
jmaki.publish('/jmaki/mapLocation','" + cb.getAddress() + "');

To subscribe to this publisher a subscriber has to be added to glue.js,
jmaki.subscribe("/jmaki/mapLocation", function(loc) {
var location = "location="+ loc;
jmaki.doAjax({
url: jmaki.xhp + "?key=yahoogeocoder&urlparams=" + encodeURIComponent(location),
callback : function(req) {
var data = eval("(" + req.responseText + ")");
jmaki.publish("/jmaki/plotmap", data.coordinates);
}
});
});

Here an outside domain is called (yahoogeocoder). One drawback of working with AJAX is that an AJAX based client
cannot make calls to URLs outside of its domain. To overcome this problem jMaki provides a generic proxy to enable calling
outside domains. It
fetches content using an HTTP client,

Transfer Solutions 2008 www.transfer-solutions.com
7
Data Binding: from JSP to JSF
Ren van Wijk
applies an XSLT transformation (data is send in XML format, it is transformed by the XSLT into JSON format),
provides a Servlet as an interface to the proxy.
Summary
A JSP page is a text-based document which describes the respective processing and generation of a request and a response.
JSP provides an expression language to access server-side objects such as JavaBeans Components. JSP also provides
mechanisms to define extensions to the JSP language such as Custom Tags.
jMaki is a lightweight framework which provides a model for AJAX enabled widgets.
JavaServer Faces (JSF)
JSF technology is a server-side user interface component framework. The main components of JSF technology are as
follows:
An API for representing UI components and managing their state; handling events, server-side validation, and data
conversion; defining page navigation; supporting internationalization and accessibility; and providing extensibility
for all these features
Two JSP custom tag libraries for expressing UI components within a JSP page and for wiring components to server-
side objects.
The well-defined programming model and tag libraries (such as Trinidad) significantly ease building web applications. The
example uses Hibernate in the model layer and Trinidad in the view layer. Here, a remark is in order, as Hibernate is used in a
JSF environment it is not mandatory to do so, it can just as well be used in a JSP environment.
Hibernate
Hibernate is an object-relational mapping tool. It helps in mapping an object data model representation to a relational model.
The figure below gives a simplified schematic representation of the Hibernate environment.
Figure 4. Hibernate environment.
To set up the development directory the required Java libraries must be added to the project. The required libraries, can be
found in the readme.txt file located in the Hibernate /lib/ directory. If Hibernate3 is used on an OC4J instance a necessary
library, antlt-2.7.6.jar, is conflicted by the shared library oracle.toplink. By adding,
<imported-shared-libraries>
<remove-inherited name="oracle.toplink"/>
</imported-shared-libraries>

to the <application-name>-oc4j-app.xml file, which located in the root of the application directory, the problem is
resolved.
For the persistence classes JavaBeans components, with standard JavaBean naming conventions and a no-argument
constructor, are used. The no-argument constructor is needed to instantiate a class through Java Reflection (allows a Java
program to inspect internal properties or to edit them during runtime). A persistence class might look like,
public class Department {
private Integer departmentNumber;
private Set employees;
public Department() {
}
public void setDepartmentNumber(Integer departmentNumber) {
this.departmentNumber = departmentNumber;
}
public Integer getDepartmentNumber() {
return departmentNumber;
Application
Persistence
Objects
Hibernate
Configuration XML Mapping
Database
Application
Persistence
Objects
Hibernate
Configuration XML Mapping
Database

Transfer Solutions 2008 www.transfer-solutions.com
8
Data Binding: from JSP to JSF
Ren van Wijk
}
public void setEmployees(Set employees) {
this.employees = employees;
}
public Set getEmployees() {
return employees;
}
}

Hibernate needs to know how to load and store objects of the persistent class. For this Hibernate uses a so-called mapping file
The mapping file tells Hibernate what table in the database it has to access, and what columns it has to use, for example,
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="datamodel.departments.Department" table="DEPT">
<id name="departmentNumber" type="int" column="DEPTNO">
<generator class="assigned"/>
</id>
<property name="departmentName" type="string" column="DNAME"/>
<property name="location" type="string" column="LOC"/>
</class>
</hibernate-mapping>

The class element persists the object Department with the table DEPT and loads this. Every instance of Department is
represented by a row. The id and property elements represent the persistence properties of the class. A mapping file should
be named as <name>.hbm.xml.
As Hibernate is the layer in the application which connects to the database connection information must be provided. To
configure Hibernate, an XML configuration file named hibernate.cfg.xml, is used. For example,
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:ORCL</property>
<property name="connection.username">example</property>
<property name="connection.password">example</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<mapping resource="datamodel\departments\Department.hbm.xml"/>
<mapping resource="datamodel\employees\Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>

The first four properties contain the necessary configuration information for a JDBC connection. The dialect property
specifies the SQL variant Hibernate will generate when connecting to the specified database. The mapping elements represent
the persistence classes. The configuration file must be placed in the root of the class path, where Hibernate automatically will
look for it at startup.
During startup a global SessionFactory is build from the information provided in the configuration file. In turn, a
SessionFactory can open new sessions (Session). A Session represents a single unit of work, for example, a request from a
client in a multi-user environment. It is best practice to strive for a single Session-per-Request, i.e.,
A request is send from a client to the server.
A new Session is opened.
All database operations are executed.
To implement this, a transaction is started when a server request has to be processed and ended just before the response is
send to the client. Once the work has been completed, the Session is closed.
The example above maps a persistent class to a single table, but as the data model shows (Figure 2) also some associations
are present. To represent this in the model two steps have be performed:
add an appropriate property to the persistence class (private Set employees),
add an association to the mapping file.
For example, the DEPT to EMP relation can be represented as,

Transfer Solutions 2008 www.transfer-solutions.com
9
Data Binding: from JSP to JSF
Ren van Wijk
<hibernate-mapping>
<class name="persistance.departments.Department" table="DEPT">

<set name="employees" lazy="false" inverse="true" cascade="save-update" sort="unsorted"
outer-join="true">
<key column="DEPTNO"/>
<one-to-many class="datamodel.employees.Employee"/>
</set>
</class>
</hibernate-mapping>

In this manner a master/detail hierarchy is created. To query the database, Hibernate provides a fully object oriented query
language. Querying the master/detail hierarchy is as simple as,
public List getData() {
String select = "from Department department"; // Define a query
Session session = HibernateUtil.getSessionFactory().getCurrentSession(); // Open new session
List result = null;
try {
session.beginTransaction();
result = session.createQuery(select).list(); // Create query and return results
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
}
return result;
}

The query result is returned in a List object. To iterate through the master/detail hierarchy, standard iteration techniques can
be used, for example,
List result = departmentData.getData();
Iterator iterator = result.iterator();
while (iterator.hasNext()) {
Department department = (Department)iterator.next();
System.out.println(department.getDepartmentName() + ", " + department.getDepartmentSalary());
Iterator employees = department.getEmployees().iterator();
while (employees.hasNext()) {
Employee employee = (Employee)employees.next();
System.out.println(" " + employee.getEmployeeName());
}
}

Here, the persistent class Employee represents the table EMP.
The session/transaction idiom to perform create, update or delete operations can be implemented as,
public void deleteData(String departmentNumber) {
Department department = new Department();
department.setDepartmentNumber(new Integer(departmentNumber));
Session session = HibernateUtil.getSessionFactory().getCurrentSession(); // Open a new session
Transaction transaction = null;
try {
transaction = session.beginTransaction(); // Start new transaction
session.delete(department); // Mark row for deletion
transaction.commit(); // Commit transaction
} catch (HibernateException e) {
try {
if (transaction != null) {
transaction.rollback(); // If commit fails rollback transaction
}
} catch (HibernateException f) {
f.printStackTrace();
}
e.printStackTrace();
}
}

The example performs a delete operation. First the key value of the row to be deleted is set. Subsequently, a new session is
opened and the transaction is started. If the transaction succeeds the transaction is committed. If it fails, the transaction is
rolled back and the session is closed. This idiom can also be used for insert and update transactions.
During runtime an object undergoes different states:
Transient - an object is transient if it is instantiated by using the new operator. It has no persistent representation in
the database and no identifier has been assigned.

Transfer Solutions 2008 www.transfer-solutions.com
10
Data Binding: from JSP to JSF
Ren van Wijk
Persistent - a persistent instance has a representation in the database and an identifier. It also has a definition in the
scope of a Session.
Detached - a detached instance is an object what has been persistent but for which the Session is closed.
Trinidad
Trinidad is a set JSF UI components built upon the JSF API. It has been donated by Oracle to the Apache open source
community. To use Trinidad, the application environment has to be configured. The Trinidad servlet filter must be added to
the web.xml file, i.e.,
<filter>
<filter-name>trinidad</filter-name>
<filter-class>org.apache.myfaces.trinidad.webapp.TrinidadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>trinidad</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<servlet>
<servlet-name>resources</servlet-name>
<servlet-class>org.apache.myfaces.trinidad.webapp.ResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>resources</servlet-name>
<url-pattern>/adf/*</url-pattern>
</servlet-mapping>

The render kit used by Trinidad must be added to the application configuration file (faces-config.xml),
<faces-config xmlns="http://java.sun.com/JSF/Configuration">
<application>
<default-render-kit-id>org.apache.myfaces.trinidad.core</default-render-kit-id>
</application>
</faces-config>

Next, add trinidad-impl-*.*.*.jar to the /WEB-INF/lib/ directory, and trinidad-impl-*.*.*.jar and trinidad-api-
*.*.*.jar to the project library. Trinidad is now ready for use.
In the following example, a structured data list is modeled in the form of a master/detail hierarchy (departments/employees).
The data used is obtained by Hibernate, which passes data as List objects. To present the data to the user, the Trinidad Table
component is used. This component is similar to the standard UIData component in JSF, but with some additional features,
including
Navigating through the model.
Sorting the model.
Selecting single or multiple items in the model.
As is clear from the bullets above a model is used by the Trinidad Table component, for example,
<tr:table id="departmentstable" value="#{departments.dataForTable}" var="row"
rowBandingInterval="1" rows="5" rowSelection="multiple"
binding="#{departments.tableDepartment}">
...
</tr:table>

Here, the attribute value represents the data model in this case a java.util.List object containing Department objects. The
attribute var represents the data iterator and the attribute rows the pagination.
Direct children of the Table component must be <tr:column> components. Every column component creates a separate
column in the table. For example,
<tr:column headerText="Department Number" sortProperty="departmentNumber"
sortable="true">
<tr:outputText value="#{row.departmentNumber}"/>
</tr:column>

The component <tr:outputText> shows the data for every row in the column using the EL expression
#{row.departmentNumber}.
To configure the table to show or hide additional details the facet detailStamp of the Table component is used. For example,
<f:facet name="detailStamp">
<tr:table value="#{row.employeesList}" var="employee">
<tr:column headerText="Employee">

Transfer Solutions 2008 www.transfer-solutions.com
11
Data Binding: from JSP to JSF
Ren van Wijk
<tr:outputText value="#{employee.employeeName} "/>
</tr:column>
</tr:table>
</f:facet>

Here a new iterator employee is defined by using the Table component. This iterator iterates through the details.
Summary
Hibernate is an object-relational mapping tool. It maps Java classes to database tables and Java data types to SQL data types.
Trinidad is a set JSF UI components with a lot of additional features.
By using Hibernate in collaboration with Trinidad, a fully object oriented environment, as shown in the example, can be
obtained.
Application Development Framework (ADF)
ADF builds upon Java EE standards and open-source technologies and offers a clean separation between:
Business logic
Page navigation
User interface
It obeys the model-view-controller architecture. The following example uses Business Components for Java in the model
layer and ADF Faces in the view layer.
Business Components for Java (BC4J)
Just as with Hibernate, a set of Java components is created to represent the database tables. To accomplish this BC4J provides
the following components:
Entity objects
o Components related to a table.
o Govern the business logic.
o Store modifications to the data.
View object
o Query components which shape the data for the user interface.
o Can reference entity objects.
Application module
o Business service client which is used to browse and modify the data.
o Uses view objects as the data model.
As with Hibernate, BC4J uses XML files to define how the database tables are structured (such as column names, data types,
etcetera).
A data model defined through BC4J is given to the view layer by so called data controls. ADF abstracts the business services
to a general layer. This general layer, called data control palette, contains:
Data collections which represent instances of the view objects.
Attributes of every data collection (Java objects of the columns).
Some handy built-in operations, such as Create, Delete etcetera.
ADF Faces and data binding
ADF Faces is an extensive library with about one hundred JSF components (it was ADF Faces which was donated as
Trinidad to the Apache open-source community). In ADF, creating pages is partially a dragging and dropping experience, for
example, drag and drop
A panelPage from the ADF Faces Core library in the component palette.
The data collection departments from the data control palette.
The detail data collection employees from the data control palette.
After adding the departments data collection as a table to the page,

Transfer Solutions 2008 www.transfer-solutions.com
12
Data Binding: from JSP to JSF
Ren van Wijk
a departments iterator is added which handles the data, and
a value binding is added with an appropriate name
to the page specific XML file (page definition file). The page definition defines the data bindings which support the UI
components on the page. At runtime an additional handler (adfBindings filter) is triggered when a user requests the page.
This handler creates an appropriate binding container for the page and makes the binding container accessible through the EL
expression #{bindings}. A schematic representation of the data binding is given in the figure below.
Figure 5. Data binding example.
The following data binding concepts can be recognized:
Binding context - the data environment for the application.
Data control - abstract implementation of the business service's application module.
Binding container - groups related iterators and control bindings bound to the page.
The binding context contains the data controls and the binding containers that use them. Each binding container has
iterator bindings which identify the data collections used by the page, and
control bindings that support the UI controls on the page.
It is also possible to access the binding container programmatically by using the EL expression #{bindings}, for example,
FacesContext fctx = FacesContext.getCurrentInstance();
ValueBinding vb = fctx.getApplication().createValueBinding("#{bindings}");
DCBindingContainer dcbc = (DCBindingContainer)vb.getValue(fctx);

From the binding container, 'bindings' objects such as iterators and control bindings can obtained as,
if (dcbc != null) {
DCIteratorBinding iterator = dcbc.findIteratorBinding("DepartmentsIterator");
List<SelectItem> selectItems = new ArrayList<SelectItem>();
for (Row row: iterator.getAllRowsInRange()) {
selectItems.add(new SelectItem(row.getAttribute("Deptno"),
row.getAttribute("Dname").toString()));
}
OperationBinding ob = dcbc.getOperationBinding("Execute");
if (ob != null) {
ob.execute();
} else {
throw new RuntimeException("No execute action present");
}
}

The example obtains an iterator which represents the departments view object. This iterator is subsequently used to create a
List containing SelectItem objects, which could, for example, be used on a page as the model for a selectOneChoice
component. To programmatically execute operations which are defined in the page definition file, first an operation binding
has to be obtained by using the name of the operation. If this operation is presented it is executed, if not an exception is
thrown.
JSF Page
Binding Container (#{bindings})
Data Control
Binding
Context
(#{data})
Model Layer
View Layer
Business
Service
Layer
Departments DepartmentsEmployeesInDepartment
DepartmentsIterator EmployeesInDepartmentIterator
Departments EmployeesInDepartment
JSF Page
Binding Container (#{bindings})
Data Control
Binding
Context
(#{data})
Model Layer
View Layer
Business
Service
Layer
Departments DepartmentsEmployeesInDepartment
DepartmentsIterator EmployeesInDepartmentIterator
Departments EmployeesInDepartment

Transfer Solutions 2008 www.transfer-solutions.com
13
Data Binding: from JSP to JSF
Ren van Wijk
ADF Life Cycle
During the processing of the request the JSF life cycle is started.
Figure 6. JSF life cycle with the extra steps performed by ADF.
By using standard mechanisms, ADF performs extra steps before or after certain phases in the JSF life cycle (see Figure 6).
This in order to
prepare the data that has to be shown,
invoke built-in operations,
modify and validate data for the view objects in the application module's data model.
At startup of an ADF application the following components are involved:
FacesServlet - Maintains the life cycle of all JSF applications.
ADFBindingFilter - Initializes the binding context for a HTTP session of a user and notifies data control instances
for upcoming requests and that a response has been send.
DataBindings.cpx - Defines the binding context for the application. It contains metadata to create binding objects,
i.e., binds pages to their corresponding page definition files and defines the data controls.
During startup the application loads the ADFBindingFilter and the DataBinding.cpx file. The life cycle passes the URL of
the requested page to the binding context. The binding context binds the URL to a page definition file using information from
the DataBindings.cpx file. The binding context instantiates the binding container and registers the data controls.
Summary
ADF obeys the model-view-controller architecture. The example used BC4J for the data model. ADF Faces, donated as
Trinidad to Apache, offers an extensive JSF components library with a lot of extra features.
Epilogue
By progressing through the different technologies, a lot of different possibilities in how to build a data bound application are
offered.
The JSP technology example used plain JDBC to access the data in the database. This data was then presented through
JavaBeans components as Java objects to the application. The user interface possibilities in the JSP environment are
somewhat limited. It is, however, possible to create your own widgets by using custom tags. The jMaki widgets are in this
respect a very fresh wind in the JSP environment.
The JSF example used Hibernate for data access. As remarked, using Hibernate is not restricted to the JSF environment it can
just as well be put to work in a JSP environment. Hibernate offers object-relational mapping. In this context there are a lot of
possibilities to model the data. As discussed in the example, data can be readied for a master/detail hierarchy. This hierarchy
is easily mapped to user interface components which are provided by JSF, especially Trinidad components which have the
basic characteristics of the standard components but with a lot of additional features.
ADF offers its own data modeling tools, such as BC4J. These tools just as Hibernate offer a object-relational mapping. ADF
also offers an extensive library of JSF components.
Request
Restore
View
Apply Request
Values
Process
Validations
Update Model
Values
Invoke
Application
Render
Response
Response
Initialize
Context
Prepare
Model
Use page definition file to
create the binding container.
Refresh the binding container
(page parameters in the page
definition are bound to a value).
Initialize
Context
Invoke model layer
validations. after
phase
after
phase
before
phase
Initialize
Context
Prepare
Model
Prepare
Render
Page definition for the next page is initialized (navigation only).
Bind page parameters (navigation only).
Refresh binding container.
Request
Restore
View
Apply Request
Values
Process
Validations
Update Model
Values
Invoke
Application
Render
Response
Response
Initialize
Context
Prepare
Model
Use page definition file to
create the binding container.
Refresh the binding container
(page parameters in the page
definition are bound to a value).
Initialize
Context
Invoke model layer
validations. after
phase
after
phase
before
phase
Initialize
Context
Prepare
Model
Prepare
Render
Page definition for the next page is initialized (navigation only).
Bind page parameters (navigation only).
Refresh binding container.

Transfer Solutions 2008 www.transfer-solutions.com
14
Data Binding: from JSP to JSF
Ren van Wijk
All in all there is a lot to choose from. To prefer one technology above the other is a personal opinion. Seeing how things are
progressing, i.e., that data modeling becomes more and more advanced (plain JDBC to Hibernate), or building user interfaces
by data bound components (plain HTML to Trinidad components) makes the Java EE platform large and very interesting.
About the author
After studying at the Delft University of Technology, Ren worked at TNO for six years. In this period, he was involved in
the development and design of various systems as an analyst/project manager. In 2006 he accepted a new position at Transfer
Solutions where he continues to build systems, as well as educate new employees in Java EE technologies.









Transfer Solutions 2008 www.transfer-solutions.com
15
Data Binding: from JSP to JSF
Ren van Wijk





Transfer Solutions
Stationsweg 19
4141 HB Leerdam
T 0345 616 888
F 0345 616 300
E info@transfer-solutions.com
www.transfer-solutions.com

2008 Transfer Solutions BV
Data Binding: from JSP to JSF
Ren van Wijk

Anda mungkin juga menyukai