Académique Documents
Professionnel Documents
Culture Documents
Column Type
ID int
CITY varchar(80)
AIRPORT char(3)
SEATS int
Column Type
ID int
AIRPORT char(3)
TIME time
SEATS int
cities where the conference will be held and may select any one of them where space
is available. Doing so should hold his or her seat in the database by starting a trans-
action. This will ensure that the user doesn’t lose his or her seat while selecting the
shuttle in the second step. The third and fourth steps in the process are to have the
user review his or her selections and confirm them—committing the changes to the
database—or abort the process, rolling back the selections to free them for other,
less fickle attendees.
To maintain a transaction across
several pages like this we’ll need to use
JSP’s session management capabilities
to store our connection to the data-
base, which we’ll wrap in the Connec-
tionBean we built earlier in this
chapter. This will allow our transac-
tion to span each page in the process.
The pages, in order of application
flow, are shown in figure 7.3. As you Figure 7.3 The JSP pages of our
can see, we’ve also created a separate registration
error page we can use to report any
problem with the database or other element of the application.
Step 1: conference.jsp
The responsibilities of the conference selection page (figure 7.4) are to present the
user with a list of conference cities, pulled from the database, and allow him/her to
select any of them which have openings. The source code is shown in listing 7.3.
This is the entry point into our application, but because our simple Connection-
Bean shields the database information from the page, we needn’t do anything spe-
cial to configure it. In fact, each page in our application starts with a block of code
to import our database classes and reference the ConnectionBean from the session,
or—in this case—create a ConnectionBean and place it into the session.
Once we have a connection to the database we can simply build our form using
data from the CONFERENCE table by executing the appropriate query and looping
through it with a while loop. For each row in the table, we verify that there are
seats available before adding a radio button for this city, ensuring that we don’t
allow the user to pick a conference that is full. We use the ID of each conference as
the value of the radio button, to which we have given the name show. We’ll use that
in the next page to hold their seat at the conference. The rest of the code is pretty
straightforward HTML. Clicking the Next button directs the user to the next page
of the application, shuttle.jsp (figure 7.5).
Step 2: shuttle.jsp
The shuttle selection page has a double duty. First it has to act on the information
gathered on the conference selection page. We have to reserve the user a seat at the
selected conference. Secondly, we have to allow the user to pick a conference shuttle
202 CHAPTER 7
Working with databases
selection based on which conference city he/she will be visiting. The source appears
in listing 7.4.
<%
String showID = request.getParameter("show");
connection.setAutoCommit(false);
String sql;
sql = "UPDATE conferences set seats=seats-1 where id=" + showID;
connection.executeUpdate(sql);
%>
<html>
<body>
<center>
<font size="+2" face="arial"><b>Shuttle Reservation</b></font>
<form action="confirm.jsp" method="post">
<table border=1 bgcolor="tan" width="50%" align="center">
<tr><td>
<table border="0" bgcolor="white" cellspacing=0 width="100%">
<tr bgcolor="tan"><th> </th>
<th>Airport</th><th>Time</th><th>Seats Available</th></tr>
<%
sql = "SELECT s.* from shuttles s, conferences c where c.id=" +
showID + " and s.airport = c.airport";
ResultSet results = connection.executeQuery(sql);
while (results.next()) {
if (results.getInt("seats") > 0) {
%>
<td>
<input type="radio" name="shuttle"
value="<%= results.getString("id") %>">
</td>
<% } else { %>
<td> </td>
<% } %>
<td><%= results.getString("airport") %></td>
<td><%= results.getTime("time") %></td>
<td align="center"><%= results.getString("seats") %></td>
</tr>
<% } %>
</table>
</td></tr></table>
Example: JSP conference booking tool 203
<p>
<input type="hidden" name="show" value="<%= showID %>">
<input type="submit" value="Next (Review Reservations)">
</form>
</center>
</body>
</html>
Now, after grabbing a reference to the ConnectionBean from the session, we grab
the selected show ID from the request and stash it in a local variable. We’ll need it
to update the database, plus we’ll pass it on to the pages that follow so we can sum-
marize the user’s selections on the last page.
String showID = request.getParameter("show");
We now actually reserve the user a seat at his or her selected conference, by reduc-
ing the open seat count by one. Before we do this however, we turn off the auto-
commit feature of the database, thereby starting a transaction.
Generating our input form is no different than on the first page of the applica-
tion, though the database query is more complicated.
"SELECT s.* from shuttles s, conferences c WHERE c.id=" +
showID + " and s.airport = c.airport"
Which, in English, means “perform a join on the tables shuttles and confer-
ences, keeping only the shuttle table’s columns, and select only those rows where
the conference ID is 12 and the conference and shuttle are associated with the same
airport.” This gives us a subset of the available shuttles, showing only those avail-
able for our selected city. (Note that we can specify a table alias after each table’s
name (the s and c values) which keeps us from having to spell out the full table
name each time we use it in the application.)
We then loop through the result set as before, again not allowing the user to
select an entry that is already full. We’ll still need the showID selected in the original
page later in the application, so we’ll carry that on through a hidden form field.
<INPUT TYPE="HIDDEN" NAME="show" VALUE="<%= showID %>">
We could have placed it into the session, but this is just as easy for now and
involves fewer steps. Figure 7.6 shows how the user confirms his/her reservation.
204 CHAPTER 7
Working with databases
Step 3: confirm.jsp
On this page we must reserve the user’s seat on the selected shuttle, display a sum-
mary of his/her selections from the first two screens, and then ask the user to either
commit or cancel the reservation. Here in listing 7.5 is source code for the page:
<p>
<input type="submit" name="commit" value="Commit Reservation">
<input type="submit" name="rollback" value="Cancel Reservations">
</body>
</html>
Again, there’s not much new here. We decrement the appropriate shuttle seat
count, just as we did earlier with the conference. We’ve now made all the changes
we plan to make to the database, but remember we are still under transaction con-
trol since we turned off autocommit earlier. We have to disable autocommit only
once, because it is a property of our connection, which we have stored in our ses-
sion via the ConnectionBean.
sql = "UPDATE shuttles set seats = seats - 1 where id = " + shuttleID;
connection.executeUpdate(sql);
The query to get the summary information is a little complicated; we could have
broken it into a couple of separate queries, extracting the appropriate data from
each. However, it’s not necessary.
sql = "SELECT c.city, c.airport, s.time from conferences c, shuttles s where
c.id=" + showID + " and s.id=" + shuttleID;
This selects the columns we are interested in from the intersection of the CONFER-
ENCE and SHUTTLES table where the corresponding ID values match the two selec-
tions the user already made. At that point, we are ready to move on to the final page
(figure 7.7), which, depending on which button the user clicks, will commit the
transaction or roll it back.
206 CHAPTER 7
Working with databases
Step 4: finish.jsp
Listing 7.6 is the final segment of our application.
<p>
<a href="conference.jsp">Book Another Reservation</a>
</body>
</html>
If the user selected the Commit button, it will show up as a request parameter. If we
detect this we’ll commit the transaction. Otherwise, we’ll call rollback:
if (request.getParameter("commit") != null)
connection.commit();
else
connection.rollback();
After saving our changes, we must get rid of that ConnectionBean to free its
resources, including the database we’ve been holding. So, we simply remove the
connection object from the session.
session.removeAttribute("connection");
The last step is to give the user feedback, with an if block, based on his/her deci-
sion. All in all the flow through this example is straightforward and linear. To wrap
this example up, let’s look at the error page.
session.removeAttribute("connection");
}
catch (SQLException e) { }
}
%>
<center>
<font size="+2" face="arial"><b>Application Error</b></font>
<p>
An error has occurred: <tt><%= exception %></tt>
<p>
<a href="conference.jsp">Book Another Reservation</a>
</center>
</body>
</html>
On this page we try to clean up some things and let the user know what has hap-
pened. In the code we abort our transactions and remove the connection object
from our session when an error occurs. We’ll see more detailed discussion on creat-
ing error pages in chapter 11.