Objectives
In this chapter you’ll learn:
• To use data providers to access databases from web applications built in Netbeans.
• The basic principles and advantages of Ajax technology.
• To use Ajax-enabled JSF components in a Netbeans web application project.
• To configure virtual forms that enable subsets of a form’s input components to be submitted to the server.
Whatever is in any way beautiful hath its source of beauty in itself, and is complete in itself; praise forms no part of it.
—Marcus Aurelius Antoninus
There is something in a face, An air, and a peculiar grace, Which boldest painters cannot trace.
—William Somerville
Cato said the best way to keep good acts in memory was to refresh them with new.
—Francis Bacon
I never forget a face, but in your case I’ll make an exception.
—Groucho Marx
Painting is only a bridge linking the painter’s mind with that of the viewer.
—Eugéne Delacroix
Outline
22.1 Introduction
22.2 Accessing Databases in Web Applications
22.2.1 Building a Web Application That Displays Data from a Database
22.2.2 Modifying the Page Bean File for the AddressBook
Application
22.3 Ajax-Enabled JSF Components
22.4 Creating an Autocomplete Text Field and Using Virtual Forms
22.4.1 Configuring Virtual Forms
22.4.2 JSP File with Virtual Forms and an Autocomplete Text Field
22.4.3 Providing Suggestions for an Autocomplete Text Field
22.4.4 Displaying the Contact’s Information
22.5 Wrap-Up
This chapter continues our discussion of web application development with several advanced concepts. We discuss accessing, updating and searching databases in a web application, adding virtual forms to web pages to enable subsets of a form’s input components to be submitted to the server, and using Ajax-enabled component libraries to improve application performance and component responsiveness.
We present a single address book application developed in three stages to illustrate these concepts. The application is backed by a Java DB database for storing the contact names and their addresses.
The address book application presents a form that allows the user to enter a new name and address to store in the address book, and it displays the contents of the address book in table format. It also provides a search form that allows the user to search for a contact and, if found, display the contact’s address. The first version of this application demonstrates how to add contacts to the database and how to display the list of contacts in a JSF Table component. In the second version, we add an Ajax-enabled Autocomplete Text Field component and enable it to suggest a list of contact names as the user types. When the user selects a contact, the contact’s information is displayed.
This chapter’s examples, like those in Chapter 21, were developed in Netbeans. Some of the Woodstock components that come with Netbeans, such as the Text Field component, are Ajax enabled. These components use the Dojo Toolkit on the client side in the web browser. Dojo is a cross-browser, cross-platform JavaScript library for creating rich client-side user interfaces and performing Ajax interactions with web servers. For more information on this toolkit, see our Dojo Resource Center at www.deitel.com/dojo/.
Many web applications access databases to store and retrieve persistent data. In this section, we build a web application that uses a Java DB database to store contacts in the address book and display contacts from the address book on a web page.
The web page enables the user to enter new contacts in a form. This form consists of Text Field components for the contact’s first name, last name, street address, city, state and zip code. The form also has a Submit button to send the data to the server and a Clear button to reset the form’s fields. The application stores the address book information in a database named AddressBook
, which has a single table named Addresses
. (We provide this database in the examples directory for this chapter. You can download the examples from www.deitel.com/books/javafp/). This example also introduces the Table JSF component, which displays the addresses from the database in tabular format.
We now explain how to build the AddressBook
application’s GUI and set up a data binding that allows the Table component to display information from the database. We present the generated JSP file later in the section, and we discuss the related page bean file in Section 22.2.2. To build the AddressBook
application, perform the following steps:
In Netbeans, create a new Web Application project named AddressBook
. Be sure to select Visual Web JavaServer Faces as the framework, as you did in Chapter 21. Rename the JSP and page bean files from Page1
to AddressBook
using the refactoring tools.
In Design mode, create the form shown in Fig. 22.1. Add a Static Text component containing "Add a contact to the address book:"
. Use the component’s style
property to set the font size to 18px
. Add six pairs of Label and Text Field components to the page. Rename the Text Fields firstNameTextField
, lastNameTextField
, streetTextField
, cityTextField
, stateTextField
and zipTextField
. Set each Text Field’s required
property to true
(checked) by selecting the Text Field, then clicking the required
property’s checkbox. Associate each Label with its corresponding Text Field by holding the Ctrl and Shift keys, then draggging the label to the appropriate Text Field. Add a binding attribute to the page bean for each Text Field (right click the component and select Add Binding Attribute). Finally, add Submit and Clear buttons. Set the Submit button’s primary
property to true
(checked) to make it more prominent on the page than the Clear button and to allow the user to submit a new contact by pressing Enter rather than by clicking the button. Set the Clear button’s reset
property to true
(checked) to prevent validation when the user clicks the button—since we’re clearing the fields, we don’t need to ensure that they contain information. We discuss the Submit button’s action handler when we present the page bean file. The Clear button does not need an action-handler method—setting reset
to true
automatically configures the button to reset all of the page’s input fields.
Fig. 22.1. AddressBook
application form for adding a contact.
Drag a Table component from the Basic section of the Palette to the page and place it just below the two Button components. Name it addressesTable
. The Table component formats and displays data from database tables. In the Properties window, change the Table’s title
property to Contacts
. We show how to configure the Table to interact with the AddressBook
database shortly.
This example uses a database called AddressBook
to store the address information. To create this database, perform the following steps:
1. In the Netbeans Services tab (to the right of the Projects and Files tabs), expand the Databases node, then right click Java DB and select Create Database....
2. Enter the name of the database to create (AddressBook
), a username (test
) and a password (test
).
3. If you wish to change the location where the database is stored on your system, click the Properties... button and specify the new location.
4. Click OK to create the database.
In the Services tab, the preceding steps create a new entry in the Databases node showing the URL of the database (jdbc:derby://localhost:1527/AddressBook
). The new Java DB database resides on the local machine and accepts connections on port 1527.
AddressBook
DatabaseYou can use the Services tab to create tables and to execute SQL statements that populate the database with data:
1. In the Services tab and expand the Databases node.
2. Netbeans must be connected to the database to execute SQL statements. If Net-beans is already connected to the database, the icon is displayed next to the database’s URL (jdbc:derby://localhost:1527/AddressBook
). In this case, proceed to Step 3. If Netbeans is not connected to the database, the icon appears next to the database’s URL. In this case, right click the icon and select Connect.... Once connected, the icon changes to .
3. Expand the node for the AddressBook
database, right click the Tables node and select Execute Command... to open a SQL Command editor in Netbeans. We provided the file AddressBook.sql
in this chapter’s examples folder. Open that file in a text editor, copy the SQL statements and paste them into the SQL Command editor in Netbeans. Then, highlight all the SQL commands, right click inside the SQL Command editor and select Run Selection. This will create the Addresses
table with the sample data shown in Fig. 22.2. You may need to refresh (right click it and select Refresh) and expand the Tables node to see the new table. You can view the data in the table by expanding the Tables node, right clicking ADDRESSES and selecting View Data....
Fig. 22.2. Addresses
table data.
Addresses
Table of the AddressBook
DatabaseNow that we’ve configured the AddressBook database and created the Addresses
table, let’s configure the Table component to display the AddressBook
data. Drag the database table from the Services tab and drop it on the Table component to create the binding.
To select specific columns to display, right click the Table component and select Bind to Data to display the Bind to Data dialog containing the list of the columns in the Addresses
database table (Fig. 22.3). The items under the Selected heading will be displayed in the Table. To remove a column, select it and click the < button. We’d like to display all the columns in this example, so you should simply click OK to exit the dialog.
Fig. 22.3. Dialog for binding to the Addresses
table.
By default, the Table uses the database table’s column names in all uppercase letters as headings. To change these headings, select a column and edit its headerText
property in the Properties window. To select a column, click the column’s name in the Design mode. We also changed the id
property of each column to make the variable names in the code more readable. In Design mode, your Table’s column heads should appear as in Fig. 22.4. If any of the column heads wrap to two lines, you can increase the width of the table.
Fig. 22.4. Table
component after binding it to a database table and editing its column names for display purposes.
An address book might contain many contacts, so we’d like to display only a few at a time. Setting the table’s paginationControls
property to true
(checked) in the Properties window configures this Table for automatic pagination. This adds buttons to the bottom of the Table for moving forward and backward between groups of contacts. You may use the Table Layout dialog’s Options tab to select the number of rows to display at a time. To view this tab, right click the Table’s header, select Table Layout..., then click the Options tab. For this example, we set the Page Size property to 5
. Click the OK button to apply the changes.
Next, set the addressesTable
’s internalVirtualForm
property to true
(checked). Virtual forms allow subsets of a form’s input components to be submitted to the server. Setting this property prevents the pagination control buttons on the Table from submitting the Text Fields on the form every time the user wishes to view the next group of contacts. Virtual forms are discussed in Section 22.4.1.
Binding the Table component to a data provider added the object addressesDataProvider
(an instance of class CachedRowSetDataProvider
) to the AddressBook node in the Navigator window. A CachedRowSetDataProvider
provides a scrollable RowSet
that can be bound to a Table component to display the RowSet
’s data. This data provider is a wrapper for a CachedRowSet
object. If you click the addressesDataProvider node in the Navigator window, you can see in the Properties window that its CachedRowSet
property is set to addressesRowSet
, a session bean property that implements interface CachedRowSet
.
addressesRowSet
’s SQL StatementThe CachedRowSet
object wrapped by our addressesDataProvider
is configured by default to execute a SQL query that selects all the data in the Addresses
table of the AddressBook
database. You can edit this SQL query. To do so, ensure that you are in Design mode for the page bean, then expand the SessionBean1
node in the Navigator window and double click the addressesRowSet
element to open the query editor window (Fig. 22.5). We’d like to edit the SQL statement so that records with duplicate last names are sorted by last name, then by first name. To do this, click the Sort Type column next to the LASTNAME row and select Ascending. Then, repeat this for the FIRSTNAME row. Notice that the expression
ORDER BY TEST.ADDRESSES.LASTNAME ASC, TEST.ADDRESSES.FIRSTNAME ASC
was added to the end of the SQL statement at the bottom of the editor. Save your application (File > Save All), then close the query editor tab.
Fig. 22.5. Editing addressesRowSet
’s SQL statement.
It is important to validate the form data on this page to ensure that the data can be successfully inserted into the AddressBook
database. All of the database’s columns are of type varchar
(except the ID column) and have length restrictions. For this reason, you should either add a Length Validator to each Text Field component or set each Text Field component’s maxLength
property. We chose to do the latter. The first name, last name, street, city, state and zip code Text Field components may not exceed 30, 30, 150, 30, 2 and 5 characters, respectively.
Finally, drag a Message Group component onto your page to the right of the Text Fields. This component displays system messages. We use it to display an error message when an attempt to add a contact to the database fails. Set the Message Group’s showGlobalOnly
property to true
(checked) to prevent component-level validation error messages from being displayed here.
The JSP file for the application is shown in Fig. 22.6. This file contains a large amount of generated markup for components you learned in Chapter 21. We discuss the markup for only the components that are new in this example.
Fig. 22.6. AddressBook
JSP with an add form and a Table JSF component
(a) Adding a new contact to the database.
(b) Page 2 of the Table showing the new database entry.
Lines 18–72 contain the JSF components for the form that gathers user input. Lines 73–120 define the Table element (webuijsf:table
) that displays address information from the database. Tables may have multiple groups of rows displaying different data. This Table has a single webuijsf:tableRowGroup
with a start tag in lines 79–81. The row group’s sourceData
attribute is bound to our addressesDataProvider
in the page bean and given the variable name currentRow
. The row group also defines the Table’s columns. Each webuijsf:tableColumn
element (e.g., lines 82–88) contains a webuijsf:staticText
element with its text
attribute bound to a column in the data provider currentRow
. These webuijsf:staticText
elements enable the Table to display each row’s data.
AddressBook
ApplicationFigure 22.7 displays the SessionBean1.java
file generated by Netbeans for the AddressBook
application. The CachedRowSet
that the Table component’s data provider uses to access the AddressBook
database is a property of this class (lines 31–41). The _init
method (lines 13–29) configures addressesRowSet
to interact with the AddressBook
database). Lines 15–16 connect the row set to the database. Lines 17–27 set addressesRowSet
’s SQL command to the query configured in Fig. 22.5. Line 28 sets the RowSet
’s table name.
Fig. 22.7. Session bean initializes the data source for the AddressBook
database.
AddressBook
ApplicationAfter building the web page and configuring the components used in this example, double click the Submit button to create its action event handler in the page bean file. The code to insert a contact into the database is placed in this method. The page bean with the completed event handler is shown in Fig. 22.8 below.
Fig. 22.8. Page bean for adding a contact to the address book.
Line 17 in method _init
sets the Table component’s internalVirtualForm
property to true
. This prevents the pagination control buttons on the Table from submitting the form’s Text Fields every time the user wishes to view the next group of contacts. Lines 18–20 set the addressesDataProvider
’s CachedRowSet
so the table rows can be populated with the contents of the database.
Lines 179–223 contain the event-handling code for the Submit button. Line 182 determines whether a new row can be appended to the data provider. If so, we append a new row (line 187). Every row in a CachedRowSetDataProvider
has its own key; method appendRow
returns the key for the new row. Line 188 sets the data provider’s cursor to the new row, so that any changes we make to the data provider affect that row. Lines 191–202 set each of the row’s columns to the values the user entered in the corresponding Text Fields. Line 205 stores the new contact by calling method commitChanges
of class CachedRowSetDataProvider
to insert the new row into the AddressBook
database.
Lines 208–213 clear the form’s Text Fields. If these lines are omitted, the fields will retain their current values after the database is updated and the page reloads. Also, the Clear button will not work properly if the Text Fields are not cleared. Rather than emptying the Text Fields, it resets them to the values they held the last time the form was submitted.
Lines 215–219 catch any exceptions that might occur while updating the AddressBook
database. If an exception occurs, lines 217–218 display a message in the page’s MessageGroup
component indicating that the database was not updated and showing the exception’s error message.
In method prerender
, we added line 153 which calls CachedRowSetDataProvider
method refresh
to reexecute the wrapped CachedRowSet
’s SQL statement and re-sort the Table’s rows so that the new row is displayed in the proper order. If you do not call refresh
, the new address is displayed at the end of the Table (since we appended the new row to the end of the data provider). The IDE automatically generated code to free resources used by the data provider (line 159) in the destroy
method. Run the application to test its functionality.
The term Ajax—short for Asynchronous JavaScript and XML—was coined by Jesse James Garrett of Adaptive Path, Inc. in February 2005 to describe a range of technologies for developing highly responsive, dynamic web applications. Ajax applications include Google Maps, Yahoo’s FlickR and many more. Ajax separates the user interaction portion of an application from its server interaction, enabling both to proceed asynchronously in parallel. This enables Ajax web-based applications to perform at speeds approaching those of desktop applications, reducing or even eliminating the performance advantage that desktop applications have traditionally had over web-based applications. This has huge ramifications for the desktop applications industry—the applications platform of choice is starting to shift from the desktop to the web. Many people believe that the web—especially in the context of abundant open-source software, inexpensive computers and exploding Internet bandwidth—will create the next major growth phase for Internet companies.
Ajax makes asynchronous calls to the server to exchange small amounts of data with each call. Where normally the entire page would be submitted and reloaded with every user interaction on a web page, Ajax allows only the necessary portions of the page to reload, saving time and resources.
Ajax applications typically make use of client-side scripting technologies such as JavaScript to interact with page elements. They use the browser’s XMLHttpRequestObject
to perform the asynchronous exchanges with the web server that make Ajax applications so responsive. This object can be used by most scripting languages to pass XML data from the client to the server and to process XML data sent from the server back to the client.
Using Ajax technologies in web applications can dramatically improve performance, but programming in Ajax is complex and error prone. It requires page designers to know both scripting and markup languages. Ajax libraries—such as the Dojo Toolkit used by JSF—make it possible to reap Ajax’s benefits without the labor of writing “raw” Ajax. These libraries provide Ajax-enabled page elements that can be included in web pages simply by adding library-defined tags to the page’s markup. We limit our discussion of building Ajax applications to using the JSF Woodstock components in Netbeans.
Figure 22.9 presents the typical interactions between the client and the server in a traditional web application, such as one that uses a user registration form. First, the user fills in the form’s fields, then submits the form (Fig. 22.9, Step 1). The browser generates a request to the server, which receives the request and processes it (Step 2). The server generates and sends a response containing the exact page that the browser will render (Step 3), which causes the browser to load the new page (Step 4) and temporarily makes the browser window blank. Note that the client waits for the server to respond and reloads the entire page with the data from the response (Step 4). While such a synchronous request is being processed on the server, the user cannot interact with the client web page. Frequent long periods of waiting, due perhaps to Internet congestion, have led some users to refer to the World Wide Web as the “World Wide Wait.” If the user interacts with and submits another form, the process begins again (Steps 5–8).
Fig. 22.9. Classic web application reloading the page for every user interaction.
This model was originally designed for a web of hypertext documents—what some people call the “brochure web.” As the web evolved into a full-scale applications platform, the model shown in Fig. 22.9 yielded “choppy” application performance. Every full-page refresh required users to reestablish their understanding of the full-page contents. Users began to demand a model that would yield the responsive feel of desktop applications.
Ajax applications add a layer between the client and the server to manage communication between the two (Fig. 22.10). When the user interacts with the page, the client creates an XMLHttpRequest
object to manage a request (Step 1). The XMLHttpRequest
object sends the request to the server (Step 2) and awaits the response. The requests are asynchronous, so the user can continue interacting with the application on the client side while the server processes the earlier request concurrently. Other user interactions could result in additional requests to the server (Steps 3 and 4). Once the server responds to the original request (Step 5), the XMLHttpRequest
object that issued the request calls a client-side function to process the data returned by the server. This function—known as a callback function—uses partial page updates (Step 6) to display the data in the existing web page without reloading the entire page. At the same time, the server may be responding to the second request (Step 7) and the client side may be starting to do another partial page update (Step 8). The callback function updates only a designated part of the page. Such partial page updates help make web applications more responsive, making them feel more like desktop applications. The web application does not load a new page while the user interacts with it.
Fig. 22.10. Ajax-enabled web application interacting with the server asynchronously.
We now modify the AddressBook
application to provide a search form that enables the user to locate a contact and display the contact’s information. We take advantage of the Text Field component’s built-in Ajax capabilities to provide autocomplete functionality—the Text Field provides a list of suggestions as the user types. It obtains the suggestions from a data source, such as a database or web service. Eventually, the updated application will allow users to search the address book by last name. If the user selects a contact, the application will display the contact’s information in a Text Area component.
AddressBook.jsp
PageUsing the AddressBook
application from Section 22.2, drop a Static Text component named searchText
below addressesTable
. Change its text to "Search the address book by last name:"
and change its font size to 18px
. Now drag a Text Field component to the page and name it lastNameSearchTextField
. Set this field’s required
and autoComplete
properties to true
. Add a Label named nameSearchLabel
containing the text "Last name:"
to the left of the Text Field and associate it with the Text Field. Finally, add a button called searchButton
with the text Find
to the right of the Text Field.
Virtual forms are used when you would like a button to submit a subset of the page’s input fields to the server. Recall that we previously enabled the Table’s internal virtual forms so that clicking the pagination buttons would not submit the data in the Text Fields used to add a contact to the AddressBook
database. Virtual forms are particularly useful for displaying multiple forms on the same page. They allow you to specify a submitter component and one or more participant components for a form. When the virtual form’s submitter component is clicked, only the values of its participant components will be submitted to the server. We use virtual forms in our AddressBook
application to separate the form for adding a contact from the form for searching the database.
To add virtual forms to the page, right click the Submit button on the upper form and select Configure Virtual Forms... to display the Configure Virtual Forms dialog. Click New to add a virtual form, then click in the Name column and change the new form’s name to addForm
. Double click the cell under the Submit column and change the option to Yes to indicate that this button should be used to submit the addForm
virtual form. Click OK to exit the dialog. Next, hold the Ctrl key and click each of the Text Fields used to enter a contact’s information in the upper form. Right click one of the selected Text Fields and choose Configure Virtual Forms.... Double click the cell under the addForm's
Participate column to change the option to Yes, indicating that the values in these Text Fields should be submitted to the server when the form is submitted. Click OK to exit.
Repeat the process described above to create a second virtual form named searchForm
for the lower form. The Find Button
should submit the searchForm
, and lastNameSearchTextField
should participate in the searchForm
. Figure 22.11 shows the Configure Virtual Forms dialog after both virtual forms have been added.
Fig. 22.11. Configure Virtual Forms dialog.
Next, return to Design mode and click the Show Virtual Forms button () at the top of the Visual Designer panel to display a legend of the virtual forms on the page. Your virtual forms should be configured as in Fig. 22.12. The Text Fields outlined in blue participate in the virtual form addForm
. Those outlined in green participate in the virtual form searchForm
. The components outlined with a dashed line submit their respective forms. A color key is provided at the bottom right of the Design area so that you know which components belong to each virtual form.
Fig. 22.12. Virtual forms legend.
Figure 22.13 presents the JSP file generated by Netbeans for this stage of the AddressBook
application. We focus only on the new features of this JSP.
Fig. 22.13. AddressBook
JSP with an AutoComplete Text Field component.
(a) User begins typing in the Text Field, and a list of last names that start with the Text Field’s contents are displayed
(b) User selects a name, which is then displayed in the Text Field
(c) User clicks Find to locate the contact’s data, which is then displayed in the Text Area
Lines 17–22 configure the virtual forms for this page. Lines 137–141 define the Text Field component with the autocomplete functionality. Notice that the Text Field’s autoComplete
attribute is set to "true"
, which enables the component to submit Ajax requests to the server. The Text Field’s autoCompleteExpression
attribute is bound to the method that will be called (SessionBean1.getOptions
) to provide the list of options the Text Field component should suggest. We discuss how to implement this method in Section 22.4.3.
Figure 22.14 displays the application’s session bean file. It includes the getOptions
method, which provides the suggestions for the autocomplete Text Field. Much of the code in this file is identical to Fig. 22.7, so we discuss only the new features here.
Fig. 22.14. Session bean initializes the data source for the AddressBook
database and provides Options
for the autocomplete capability.
Method getOptions
(lines 96–148) is invoked after every keystroke in the autocomplete Text Field to update the list of suggestions based on what the user typed. The class in which you define getOptions
must implement the interface AutoComplete
(package com.sun.webui.jsf.model
), which declares a getOptions
method that receives a string (filter
) containing the text the user has entered and returns an array of Option
s (package com.sun.webui.jsf.model
) to be displayed by an autocomplete Text Field. The method iterates through the addressesDataProvider
, retrieves the name from each row, checks whether the name begins with the letters typed so far and, if so, adds the name to list
(an ArrayList
of Option
s created at line 99). Lines 102–104 get the AddressBook
bean and use it to obtain the addressesDataProvider
. Line 109 sets the cursor to the first row in the data provider. Line 112 determines whether there are more rows in the data provider. If so, lines 115–119 retrieve the last and first names from the current row and create a String
in the format last name, first name. Line 123 compares the lowercase versions of name
and filter
to determine whether the name
starts with the characters in filter
(i.e, the characters typed so far). If so, the name is a match and line 125 adds it to list
.
Recall that the data provider wraps a CachedRowSet
object that contains a SQL query which returns the rows in the database sorted by last name, then first name. This allows us to stop iterating through the data provider once we reach a row whose name comes alphabetically after the text entered by the user—names in the rows beyond this will all be alphabetically greater and thus are not potential matches. If the name
does not match the text entered so far, line 131 tests whether the current name is alphabetically greater than the filter
. If so, line 133 terminates the loop.
Performance Tip 22.1
When using database columns to provide suggestions in an autocomplete Text Field, sorting the columns eliminates the need to check every row in the database for potential matches. This significantly improves autocomplete performance when dealing with a large database.
If the name is neither a match nor alphabetically greater than filter
, line 138 moves the cursor to the next row in the data provider. While there are more rows, the loop checks whether the name in the next row matches the filter
and should be added to list
.
Lines 141–145 catch any exceptions generated while searching the database. Lines 143–144 add text to the suggestion box indicating the error to the user.
Once the loop terminates, line 147 converts the ArrayList
of Option
s to an array of Option
s and returns the array. The data in the array is sent to the client web browser as the response to the initial Ajax request, then used to display a drop-down list of the matching database entries. This is handled by the Dojo JavaScript code that JSF outputs to render the Text Field component on the client. The user can click one of the displayed entries to select it, then press the Find button to display the selected contact’s information. We discuss the Find button’s event handler next.
Figure 22.15 displays the page bean file for the JSP in Fig. 22.13. The event-handling method searchButton_action
displays the selected contact’s information. Much of the code in this file is identical to Fig. 22.8, so we show only the new features here.
Fig. 22.15. Page bean that suggests names in the AutoComplete Text Field.
Lines 253–276 define method searchButton_action
. Line 256 obtains the text from the lastNameSearchTextField
, then line 257 parses the name into a last name and a first name. Lines 260–262 use the addressDataProvider
’s findFirst
method to find the first entry in the database with the specified last name and first name. This method returns a RowKey
that uniquely identifies that row in the database table. Line 265 moves the cursor to that row. Lines 268–272 obtain the remaining data for the contact and build a result string, which is then displayed in the Text Area (line 274).
In this chapter, we presented a case study on building a web application that interacts with a database and provides rich user interaction using an Ajax-enabled JSF component. We first built an AddressBook
application that allowed a user to add and browse contacts. You learned how to insert user input into a Java DB database and how to display the contents of a database on a web page using a Table JSF component. You also learned that some of the Woodstock JSF components are Ajax enabled. We extended the AddressBook
application to include an autocomplete Text Field component. We showed how to use a database to display suggestions as the user types in the Text Field. You also learned how to use virtual forms to submit subsets of a form’s input components to the server for processing.
In Chapter 23, you’ll learn how to create and consume Java web services. You’ll use Netbeans to create web services and consume them from desktop and web applications.