Sunday, December 6, 2009

JSF Component Power Demonstrated through Data Table

When it comes to MVC Web frameworks in Java there are a lot of choices. The leading frameworks or "Big 3" as they are sometimes know are usually considered to be Struts, Spring MVC and JavaServer Faces (JSF). Each framework has its pros/cons, its supporters and detractors. For those looking to some for a good comprehensive comparison, you might want to check out Matt Raible's blog and presentation here.

JSF is an extremely powerful, component driven framework. In fact, its nickname is "Swing for the Web." The JSF data table serves as an excellent example of JSF's Swing-like capability. A JSF data table can display a collection of data objects while also offering features such as pagination, column header/footers, style sheet application (for header, even and odd rows, etc.).



Data Table Example

First, to familiarize you with the JSF data table, let's look at a small example. In a JSP, use the <h:dataTable…> JSF tag to define a table in your page. The <h:column …> tag helps to define the table columns while the <f:facet …> tag is used to define header and footer rows.

<f:view>

    <h:dataTable value="#{orderBean.orderModel}" var="order"

        binding="#{orderBean.orderTable}" headerClass="columnHeader"

        rowClasses="oddRow,evenRow">

        <h:column>

            <f:facet name="header">

                <h:outputText value="Description" />

            </f:facet>

            <h:outputText value="#{order.description}" />

        </h:column>

        <h:column>

            <f:facet name="header">

                <h:outputText value="Customer" />

            </f:facet>

            <h:outputText value="#{order.customer}" />

        </h:column>

        <h:column>

            <f:facet name="header">

                <h:outputText value="Price" />

            </f:facet>

            <h:outputText value="#{order.price}">

                <f:convertNumber type="currency" />

            </h:outputText>

        </h:column>

        <h:column>

            <f:facet name="header">

                <h:outputText value="Quantity" />

            </f:facet>

            <h:outputText value="#{order.quantity}" />

        </h:column>

        <h:column>

            <f:facet name="header">

                <h:outputText value="Cost" />

            </f:facet>

            <h:outputText value="#{order.cost}">

                <f:convertNumber type="currency" />

            </h:outputText>

        </h:column>

        <h:column>

            <h:form>

                <h:commandLink action="#{orderBean.editOrder}">Edit</h:commandLink>

                <f:verbatim>

                </f:verbatim>

                <h:commandLink action="#{orderBean.deleteOrder}">Delete</h:commandLink>

                <f:verbatim>

                </f:verbatim>

                <h:commandLink action="#{orderBean.displayOrder}">

                    <f:param name="id" value="#{order.id}" />Display</h:commandLink>

            </h:form>

        </h:column>

    </h:dataTable>

</f:view>

In this example a collection of Order objects is obtained from a JSF managed bean (OrderManagedBean) to populate the data table. Note the value attribute to the <h:dataTable…> element above. Unified expression language is used to bind the orderModel property of an instance of a managed bean to the data table.

The var attribute on the data table establishes the name of the variable used to reference to each object in the nested elements of the data table. In this example, the name "order" is used to reference each of the Order objects in the collection provided to the data table.

Unified expression language in the <h:column …> element allows properties of the Order objects to be obtained and displayed.

Note how cascading styles can be used to differentiate odd and even rows. Other attributes like first, rows, cellspacing, cellpadding, etc. can add pagination and better layout to the table. See the JSF API documentation for a complete list of how to customize the data table.

For completeness of the example, here is the managed bean definition for this example in the JSF faces-config.xml.

<faces-config

    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-facesconfig_1_2.xsd"

    version="1.2">

    <managed-bean>

        <managed-bean-name>orderBean</managed-bean-name>

        <managed-bean-class>com.intertech.beans.OrderManageBean</managed-bean-class>

        <managed-bean-scope>session</managed-bean-scope>

    </managed-bean>

</faces-config>

Populating a Data Table

Flexibility epitomizes JSF components. Extreme flexibility can be demonstrated by data table population and row selection. With regard to the binding, the JSF data table can be populated with an array, a List, an SQL ResultSet, a JSTL SQL Result, or even a JSF table data model object as shown here.

public class OrderManageBean {

    private ListDataModel orderModel;

    private OrderDAO dao = new OrderDAO();


    public ListDataModel getOrderModel() {

        if (orderModel == null) {

            List<Order> list = dao.getOrders();

            orderModel = new ListDataModel(list);

        }

        return orderModel;

    }


    public void setOrderModel(ListDataModel orderModel) {

        this.orderModel = orderModel;

    }


}

All that is required is that the getOrderModel( ) method must return one of these types of objects.

Selecting and Working With a Row in the Data Table

When displaying a list of objects, a common requirement is to provide a means to select an object, or more precisely an object's row, for the purpose of working with that object – for example to edit or delete the object. Again, JSF provides the flexibility to accomplish this task in many ways.

You can bind a property of the managed bean to the data table component itself. Then, call on the getRowData( ) method of the data table object to get the selected object. Below, the managed bean's edit action method uses the bound data table component to get the selected Order object.

    private UIData orderTable;

    public UIData getOrderTable() {

        return orderTable;

    }

    public void setOrderTable(UIData orderTable) {

        this.orderTable = orderTable;

    }

    public String editOrder() {

        Order o = (Order) orderTable.getRowData();

        //do work to get and edit an order

        dao.editOrder(o);

        return null;

    }


You can bind a property of the managed bean to the data table model and call on the getRowData( ) method of the model object to get the selected object. This is the case in the delete method below, which uses the bound data table model to fetch the selected Order object.

    public String deleteOrder() {

        Order o = (Order) orderModel.getRowData();

        //do work to delete order

        dao.deleteOrder(o);

        return null;

    }


Or, you can add the object's unique identifier as a parameter to the link or button in the data table (see the <h:commandLink ….> to Display above) so that when it is pushed, the object's identifier is passed to action method. The id can then be used to fetch the selected object. Here, the managed bean's details method uses the id passed via the command link in the page to fetch the selected Order to display.

    public String displayOrder() {

        Order o = (Order) orderModel.getRowData();

        //do work to get and display an order

        dao.getOrder(o);

        return null;

    }

The code for this example is available here.

Powerful JSF

Again, JSF is a very powerful MVC framework in Java. Its component nature, as represented by the data table, allows it to be customized quickly/easily and allows for great integration into technologies like AJAX. To be fair, JSF has also suffered some performance criticism (see JavaOne presentation here). As JSF 2.0 is now out, more organizations are exploring (or possibly re-exploring) it for Web applications. JSF 2.0 will be part of Java EE 6 which is expected to be released at anytime.

Intrigued by the power and capability of JSF? Come attend Intertech's Complete JSF class.


4 comments:

  1. Nice article Jim.

    You had mentioned that JSF's nickname is 'Swing for the web', but to me developing with GWT feels much more like Swing than JSF.

    While GWT is not one of the 'Big 3' MVC frameworks and doesn't have nearly the market share that the 'Big 3' frameworks have, it is quickly beginning to penetrate the corporate market. Indeed.com shows that the number of jobs containing a keyword of 'jsf' peeked in late 2008, while jobs containing a keyword of 'gwt' continue to grow at a very fast rate.

    I only mention this to bring awareness to GWT as a viable framework with capabilities that I believe are even more Swing-like than JSF.

    ReplyDelete
  2. Hi Jim I really appreciate you demonstrated the JSF Component Power through data table, I want to do the same, I want to demonstrate the advantages of Sildenafil Citrate to my colleagues

    ReplyDelete
  3. Glad to visit your site. An awesome blog. Nice Information It's really very informative that I wanted ever, thanks for this. Jual Peninggi Badan Alami Bali Ratih Obat Jerawat Obat Asam Urat Alami Kapsul Mengkudu Obat Pelangsing Badan HerbalMadu Hitam Pahit Masker Wajah Alami

    ReplyDelete