Web Application Case Study: Online Bookstore
by Dr. Wenjie He
In this lecture, we study the code of
Bookstore.
Run Example Bookstore
- Download the source code Bookstore.zip.
After you unzip the file and extract it to some directory, you get the Bookstore folder.
It is an Eclipse project folder.
- Import the project Bookstore into the Eclipse. Select File ==> Import....
The Import windows opens. Expand the General node, and select the
Existing Projects into Workspace.
- Click Next. In the new window, press the Browse... button to navigate to the
directory Bookstore you prepared above, click OK to load it. Check the box
Copy projects into workspace, and click Finish. Then the project is loaded into
the Eclipse.
- Open the build.properties file in the Text Editor of Eclipse. (Right-click the
build.properties node, select Open With ==> Text Editor. If you double-click the
node, you may open it in a different editor.)
- Verify the following parameters:
appserver.home point to your Tomcat installation directory
hsqldb.lib point to your HSQLDB library location
tomcat.manager.username your username for the Tomcat manager account
tomcat.manager.password your password for the Tomcat manager account
- Open the Ant view. Select Window ==> Show View ==> Ant.
- Load the build.xml into the Ant view. Right-click anywhere inside the Ant view area,
select Add Buildfiles.... In the Buildfile window, locate your build.xml
file and click OK to load it. Expand the AnimalSurvey node, you would see all
the Ant targets.
- Start the HSQLDB database server: double-click the dbserver node in the Ant view.
- Start the Tomcat: double-click the startTomcat node in the Ant view.
- Set up the database: double-click the setupDb node in the Ant view.
- Run the web application: double-click the runweb node in the Ant view.
You would see the Bookstore web application running in IE.
- Access the Bookstore. After you test it, you can do the following tasks to clean up.
- Stop the Tomcat: double-click the stopTomcat node in the Ant view.
- Shut down the database: double-click the shutdownDB node in the Ant view. You shut down the
bookdb database first. After that, since there is no database running in the HSQLDB
database server, the server is automatically shut down.
- Delete the database files: double-click the deleteDb node in the Ant view.
(You can decide if you want to delete it or not. If you do not delete the database, next time when
you run the web application, you can skip the setupDb step.)
Study Code of Bookstore
I. Page Flow of Bookstore
- Page index.html: the welcome page
- Click the button Click here to enter store, you would see the page book.jsp
that lists all the books in the bookstore.
- When you click a book link, you reach an individual book page singleBook.jsp,
which is redirected by the servlet BookServlet.java with alias displayBook.
- When you click the Add to Cart button, the book you select is added into the shopping cart.
This action is processed by the AddToCartServlet servlet with alias addToCart.
After the action, the viewCart.jsp is displayed.
- When you click the link Continue Shopping, you go back to the book.jsp page.
- When you click the Check Out button, you go to the order.html page.
- After you fill out the form and click the Submit button, you would see the
process.jsp page.
II. Code of BookBean.java
Code Listing:
BookBean.java
package org.me.webapps.bookstore;
// Java core packages
import java.io.*;
public class BookBean implements Serializable {
private static final long serialVersionUID = 6723471178342776147L;
private String ISBN, title, copyright, imageFile;
private int editionNumber, publisherID;
private double price;
// set ISBN number
public void setISBN( String isbn )
{
ISBN = isbn;
}
// return ISBN number
public String getISBN()
{
return ISBN;
}
// set book title
public void setTitle( String bookTitle )
{
title = bookTitle;
}
// return book title
public String getTitle()
{
return title;
}
// set copyright year
public void setCopyright( String year )
{
copyright = year;
}
// return copyright year
public String getCopyright()
{
return copyright;
}
// set file name of image representing product cover
public void setImageFile( String fileName )
{
imageFile = fileName;
}
// return file name of image representing product cover
public String getImageFile()
{
return imageFile;
}
// set edition number
public void setEditionNumber( int edition )
{
editionNumber = edition;
}
// return edition number
public int getEditionNumber()
{
return editionNumber;
}
// set publisher ID number
public void setPublisherID( int id )
{
publisherID = id;
}
// return publisher ID number
public int getPublisherID()
{
return publisherID;
}
// set price
public void setPrice( double amount )
{
price = amount;
}
// return price
public double getPrice()
{
return price;
}
}
- This JavaBean wraps all the information of a book in a well-designed data structure.
It helps organize the book information in a convevient way.
- JavaBeans provide setters and getters methods to access their properties.
III. Code of TitlesBean.java
Code Listing:
TitlesBean.java
1. package org.me.webapps.bookstore;
2.
3. // Java core packages
4. import java.io.*;
5. import java.sql.*;
6. import java.util.*;
7. import java.net.*;
8.
9. public class TitlesBean implements Serializable {
10. private static final long serialVersionUID = 6723471178342776147L;
11. private Connection connection;
12. private PreparedStatement titlesQuery;
13.
14. // construct TitlesBean object
15. public TitlesBean() {
16. // attempt database connection and setup SQL statements
17. try {
18. Class.forName("org.hsqldb.jdbcDriver");
19. connection = DriverManager.getConnection(
20. "jdbc:hsqldb:hsql://localhost/bookdb", "sa", "" );
21.
22. titlesQuery = connection
23. .prepareStatement(
24. "SELECT isbn, title, editionNumber, "
25. + "copyright, publisherID, imageFile, price "
26. + "FROM titles ORDER BY title");
27. }
28.
29. // process exceptions during database setup
30. catch (SQLException sqlException) {
31. sqlException.printStackTrace();
32. }
33.
34. // process problems locating data source
35. catch (Exception exception) {
36. exception.printStackTrace();
37. }
38. }
39.
40. // return a List of BookBeans
41. public List<BookBean> getTitles() {
42. List<BookBean> titlesList = new ArrayList<BookBean>();
43.
44. // obtain list of titles
45. try {
46. ResultSet results = titlesQuery.executeQuery();
47.
48. // get row data
49. while (results.next()) {
50. BookBean book = new BookBean();
51.
52. book.setISBN(results.getString("isbn"));
53. book.setTitle(results.getString("title"));
54. book.setEditionNumber(results.getInt("editionNumber"));
55. book.setCopyright(results.getString("copyright"));
56. book.setPublisherID(results.getInt("publisherID"));
57. book.setImageFile(results.getString("imageFile"));
58. book.setPrice(results.getDouble("price"));
59.
60. titlesList.add(book);
61. }
62. } catch (SQLException exception) {
63. exception.printStackTrace();
64. }
65.
66. return titlesList;
67. }
68.
69. // close statements and terminate database connection
70. protected void finalize() {
71. // attempt to close database connection
72. try {
73. connection.close();
74. }
75.
76. // process SQLException on close operation
77. catch (SQLException sqlException) {
78. sqlException.printStackTrace();
79. }
80. }
81. }
- (Line 18) Load the HSQLDB database driver's class from Bookstore\WEB-INF\lib.
- (Lines 19-20) Declare and initialize a Connection object that manages the
connection between the Java program and the database.
- (Line 42) List<BookBean> is a generic data type that declares a list of
BookBean objects.
IV. Code of book.jsp
Code Listing:
book.jsp
1. <?xml version = "1.0"?>
2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4. <!-- books.jsp -->
5.
6. <%-- JSP page settings --%>
7. <%@
8. page language = "java"
9. import = "org.me.webapps.bookstore.*, java.util.*"
10. session = "true"
11. %>
12.
13. <!-- begin document -->
14. <html xmlns = "http://www.w3.org/1999/xhtml">
15.
16. <head>
17. <title>Book List</title>
18.
19. <link rel = "stylesheet" href = "styles.css"
20. type = "text/css" />
21. </head>
22.
23. <body>
24. <p class = "bigFont">Available Books</p>
25.
26. <p class = "bold">Click a link to view book information</p>
27.
28. <p>
29.
30. <%-- begin JSP scriptlet to create list of books --%>
31. <%
32. TitlesBean titlesBean = new TitlesBean();
33. List titles = titlesBean.getTitles();
34. BookBean currentBook;
35.
36. // store titles in session for further use
37. session.setAttribute( "titles", titles );
38.
39.
// obtain an Iterator to the set of keys in the List
40. Iterator iterator = titles.iterator();
41.
42. // use the Iterator to get each BookBean and create
43. // a link to each book
44. while ( iterator.hasNext() ) {
45. currentBook = ( BookBean ) iterator.next();
46.
47. %> <%-- end scriptlet to insert literal XHTML and --%>
48. <%-- JSP expressions output from this loop --%>
49.
50. <%-- link to a book's information --%>
51. <span class = "bold">
52. <a href =
53. "displayBook?isbn=<%= currentBook.getISBN() %>">
54.
55. <%= currentBook.getTitle() + ", " +
56. currentBook.getEditionNumber() + "e" %>
57. </a>
58. </span><br />
59.
60. <% // continue scriptlet
61.
62. } // end while loop
63.
64. %> <%-- end scriptlet --%>
65.
66. </p>
67. </body>
68.
69. </html>
- (Line 8) The page directive specifies global settings for the JSP in the JSP
container. The language attribute specifies the scripting language used in the JSP.
Currently, the only valid value for this attribute is java.
- (Line 9) The import attribute specifies a comma-separated list of fully qualified
class names and/or packages that we will be used in the current JSP. When the scripting
language is java, the default import list is java.lang.*, javax.servlet.*,
java.servlet.jsp.*, javax.servlet.http.*.
- (Line 10) The session attribute specifies whether the page paticipates in a session.
When the value is true, it paticipates in a session -- the default; if it is
false, the page does not paticipate in a session.
- (Line 10) When the page is part of a session, the JSP implicit object session
is available for use in the page. Otherwise, session is not available.
- (Line 33) Gets a list a books from the database in the form of List<BookBean>.
- (Line 37) Stores the List<BookBean> object titles in the session
under the name "titles", which can be retrieved later through this name.
- (Lines 52-53) Forms a hyperlink using a servlet URL. When the link is clicked, the servlet
displayBook is called with value <%= currentBook.getISBN() %> for
the isbn parameter.
V. Code of BookServlet.java
Code Listing:
BookServlet.java
1. package org.me.webapps.bookstore;
2.
3. // Java core packages
4. import java.io.*;
5. import java.util.*;
6.
7. // Java extension packages
8. import javax.servlet.*;
9. import javax.servlet.http.*;
10.
11. public class BookServlet extends HttpServlet {
12. private static final long serialVersionUID = 6723471178342776147L;
13.
14. protected void doGet( HttpServletRequest request,
15. HttpServletResponse response )
16. throws ServletException, IOException {
17. HttpSession session = request.getSession( false );
18.
19. // RequestDispatcher to forward client to bookstore home
20. // page if no session exists or no books are selected
21. RequestDispatcher dispatcher =
22. request.getRequestDispatcher( "/index.html" );
23.
24. // if session does not exist, forward to index.html
25. if ( session == null )
26. dispatcher.forward( request, response );
27.
28. // get books from session object
29. List titles =
30. ( List ) session.getAttribute( "titles" );
31.
32. // locate BookBean object for selected book
33. Iterator iterator = titles.iterator();
34. BookBean book = null;
35.
36. String isbn = request.getParameter( "isbn" );
37.
38. while ( iterator.hasNext() ) {
39. book = ( BookBean ) iterator.next();
40.
41. if ( isbn.equals( book.getISBN() ) ) {
42.
43. // save the book in a session attribute
44. session.setAttribute( "bookToAdd", book );
45. dispatcher =
46. request.getRequestDispatcher( "/singleBook.jsp" );
47. dispatcher.forward( request, response );
48. }
49. }
50.
51. // if book is not in list, forward to index.html
52. if ( book == null )
53. dispatcher.forward( request, response );
54.
55. }
56.
57. }
- (Line 17) Obtains an HttpSession object for the client through the
getSession method of an HttpServletRequest object.
- (Line 17) The call request.getSession( false ) means that if the server has an existing
HttpSession object for the client from a previous request, it returns that
HttpSession object; if no existing HttpSession object, it rturns null.
- (Line 17) The call request.getSession( true ) means that if the server has an existing
HttpSession object for the client from a previous request, it returns that
HttpSession object; if no existing HttpSession object, it creates a new one.
VI. Code of singleBook.jsp
Code Listing:
singleBook.jsp
1. <%@page contentType="text/html"%>
2. <%@page pageEncoding="UTF-8"%>
3. <%@ page language = "java" session = "true" %>
4. <%@ page import = "org.me.webapps.bookstore.*" %>
5. <%@ page import = "java.text.*" %>
6.
7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
8. "http://www.w3.org/TR/html4/loose.dtd">
9.
10. <%
11. BookBean book = ( BookBean ) session.getAttribute( "bookToAdd" );
12. %>
13.
14. <html>
15. <head>
16. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
17. <title><%= book.getTitle() %></title>
18.
19. <link rel = "stylesheet" href = "styles.css"
20. type = "text/css" />
21. </head>
22. <body>
23.
24. <h1><%= book.getTitle() %></h1>
25.
26. <table>
27. <tr>
28. <!-- create table cell for product image -->
29. <td rowspan = "5"> <!-- cell spans 5 rows -->
30. <img style = "border: thin solid black" src =
31. "images/<%= book.getImageFile() %>"
32. alt = "<%= book.getTitle() %>" />
33. </td>
34.
35. <!-- create table cells for price in row 1 -->
36. <td class = "bold">Price:</td>
37.
38. <td><%= new DecimalFormat("0.00").format( book.getPrice() ) %></td>
39. </tr>
40.
41. <tr>
42.
43. <!-- create table cells for ISBN in row 2 -->
44. <td class = "bold">ISBN #:</td>
45.
46. <td><%= request.getParameter("isbn")%></td>
47. </tr>
48.
49. <tr>
50.
51. <!-- create table cells for edition in row 3 -->
52. <td class = "bold">Edition:</td>
53.
54. <td><%= book.getEditionNumber() %></td>
55. </tr>
56.
57. <tr>
58.
59. <!-- create table cells for copyright in row 4 -->
60. <td class = "bold">Copyright:</td>
61.
62. <td><%= book.getCopyright() %></td>
63. </tr>
64.
65. <tr>
66.
67. <!-- create Add to Cart button in row 5 -->
68. <td>
69. <form method = "post" action="addToCart">
70. <p><input type = "submit" value = "Add to Cart" /></p>
71. </form>
72. </td>
73.
74. <!-- create View Cart button in row 5 -->
75. <td>
76. <form method = "get" action="viewCart.jsp">
77. <p><input type = "submit" value = "View Cart" /></p>
78. <form>
79. </td>
80. </tr>
81.
82. </table>
83.
84. </body>
85. </html>
==========To Be Continued==========