Now that the FabFlixs database is built, we add functions to allow customers to browse through the movies available for purchase, search for movies by specific criteria, add movies to be purchased to their shopping cart, and to check outpurchase the movies via credit card.
A WAR file, labeled with your team name; its extension is WAR. The root directory of the WAR hierarchy is also your team name. The structure of WAR files, and how to create them, is discussed below.
Use these conventions for the database you submit:
Be sure to include all source code files (e.g., *.java files) in your WAR, in the directory sources within the WEB-INF subdirectory.
A ReadMe file explaining how to compile, load, and otherwise prepare your system for use, and how to run it.
In addition to the technologies used hereHTML, Java, JSP, sessions, servlets (deployed via Tomcat)you may use client-side scripting or programming languages (e.g., Javascript, PHP, embedded Java, style sheets) as you find appropriate; you may use other or different server-side technologies with the instructor's permission. Your program must work with a postgreSQL database having the schema developed in Phase 1.
In an actual development effort, the functional and look-and-feel requirements for FabFlixs's customer functions would have been specified in every particular. We've purposely left these requirements high-level because we want you to use your skills, experience and reasoned judgment to refine the requirements. Do feel free to ask the instructor or TA for advice! With your project manager's permission, you can enhance these specifications for potential additional creditbut be careful: including additional features that do not work will detract from your score.
Overall, the system must (of course) behave as specified, but also have an appealing, easy-to-use, and consist user interface and appropriate error handling with specific and correct error messages and actions.
Main Page. The first page the user encounters is the main page, where the customer can choose either to search for movies, browse the movies, or go to the login page. Any attempt to bypass this page should be thwarted; that is, anyone going directly to another page on the site should be redirected here. Note specifically that a user need not log in to look at what movies FabFlixs has to offer.
Browsing. If browsing is selected, the user chooses to "browse by title" or "browse by genre". In the first case, the movies will be listed on the movie list page (described below) in ascending order by title and, within title, in descending order by year; title ordering is case-insensitive. Desired, but not required for full credit, is a list of the numerals and letters at the top of the screen that, when one of them is clicked, positions the user in the movie list to the first movie that starts with that numeral or letter.
In the second case, a list of the genres appears; the user selects one. The genres are sorted in case-insensitve order, and, if two genres (without regard to case) are the same, they are listed once. (This helps us avoid problems if somehow multiple, identical genres got into the database.) A movie list page appears, consisting of the movies associated with that genre (or genres, if they are the same except for their case); they are listed in ascending order of title.
Searching. If search is selected, the customer is taken to the search page, where the customer can search for movies by any combination of the following attributes. A criterion can be one or more words (words are separated by a space); all words must be "matched" for the movie to be selected. If criteria for multiple attributes are given, the results are those that match all selected criteria (a logical "and"):
Matching is case-insensitive and each search term is partial. For example, a query asking for "term" for the title attribute should return movies where "term" is a substring of the title, such as "Terms of Endearment" "Terminator", "The End of the Term"; "endear term" would find "Terms of Endearment" and "Termites of Mendearia". For name fields that have two parts (director's name, star's name), look in both parts for a match.
When the movies appear on the movie list page (described below) they are in ascending order by title and, if two movies have the same title, within title they are sorted in descending order by year.
Movie list page. The movie list includes a list of the movies that come about because of a browse by title, browse by genre, or search.
The move list is ordered alphabetically by title, and the first 20 movies in the list (or all of them, if less than 20) that match the selection criteria appear.
Each item in the list contains
Here and elsewhere, names should appear in natural order; for example, when listing the director's name, show it in rest-of-name, last-name order.
Label each attribute so the user knows what s/he is "looking at." The exact format is up to you (but a standard one is columnar: each attribute is in its own column, with sublists (genres, stars) appearing together in the same column; each column is labeled at its head). The user can re-sort the list by title, year or director by clicking on the column heading for that attribute; repeated clicks alternate the sorting between ascending and descending order. For instance, to sort by director, one would click on that column's heading; the first click would sort in ascending order, the second click in descending order, the third back into ascending order, and so on. The first 20 items of the newly-sorted list are displayednot the current 20 items in a new order.
If there are more than 20 movies in the list, have "previous" and "next" buttons available; scroll backward and forward through the list, respectively, 20 movies at a time. (Don't show the "previous" button when at the start of a list; don't show the "next" button when at the end.)
If the user clicks on a star of this movie, the corresponding single star page displays the star's name, date of birth, picture of the star, and the title of the movies in which the star acted (each again linked to the appropriate single movie page). If this star's picture is not available, or its link is broken or points to something that is not a valid gaphic, just don't display anything or, if you wish, display a "not available" graphic of your own design.
Login page. Users reach the login page either from the main page or by clicking on the shopping cart without already being logged in. Login asks if the user is an existing customer or a new customer. If the former, the user is asked for her/his email address (which serves as a login id) and password. If the user is a new customer, login asks for the customer's first and last names, email address and password, that latter typed twice to verify it.
If users do not enter a correct login, or have errors that prevent them from registering, they are allowed to try again some limited number of times. When that limit is reached, a polite message is given and the user is "kicked back" to the main FabFlixs page.
Make sure the user name and password do not appear in the address bar or are otherwise visible in web page addresses (hint: use HTTP POST instead of HTTP GET).
Appropriate error checking during registration must be done; for instance, if a person tries to register with an email address is already on file, s/he should be told so politely, and asked for the existing password. If the user has forgotten the password, they should be directed to call the FabFlixs hotline at 1-800-FAB-FLIX or to send email to fabflixs-help@fabflixs.com; representatives will reset their password. (Web-based mechanisms for handling this issue are slated for a future release.)
Once registered successfully, the user is logged in and processing proceeds: the user goes to the shopping cart, if that is how the login page was called up; otherwise, s/he goes back to the page from which s/he came.
Shopping cart. When a user clicks the "add to shopping cart" button associated with a DVD, and, if necessary, logging in has been accomplished, and if s/he has not previously selected this DVD in this session, the DVD is added to the cart with a default quantity of 1; obviously, the DVD's title, quantity (and any other identifying information you find appropriate) is shown. If this DVD is already in the shopping cart, its quantity is increased by 1. In either case, the user remains in the shopping cart, with the cursor set in the quantity field for this DVD; the user can now change the quantity field directly. If the user changes the quantity to zero, verify that was the intent, delete the DVD from the shopping cart (and return to the cart, displaying its contents).
Check out. All pages, except the login page, have a prominent "checkout" button. If the user leaves the FabFlixs site without checking out, no session information is saved. (Tracking number of visits and related information may be added in future.) If the button is pressed, and there is at least one DVD in the shopping cart, the customer information page appears. It displays the information of each movie in the shopping cart, including the quantity of each to be purchased and the line-item price ($19.95 times the number of DVDs); the total purchase amount is also shown. The user is allowed to update or, if not yet present, provide a credit card number, the card's expiration date, and the name of the credit card holder. It is an error if the expiration date, whether just now entered or already on file, is earlier than today's date; the user should be told the expiration date is unacceptable and allowed to re-enter it.
The user is also shown the on-file address and allowed to update it; the user can also enter a shipping address; if left blank, the customer address is the shipping address. (The shipping address has the same attributes as the address in the customer table; note this address could be virtually anywhere in the world.)
The user clicks a button to confirm the data is correct; any time prior to that point, the user can abandon the purchase by leaving the page. The credit card number, card holder name, expiration date and total are sent to an as-yet-to-be-chosen credit card verification site. For this phase, we assume the data entered to be accurate and the credit purchase to be authorized. Place the order information into the sales tablethe shipping department's systems will retrieve it, process the order and update inventory records. Confirm to the user via the screen that the order has been processed.
System flow is summarized in the following diagram:
As discussed in Phase 0, Tomcat deploys WAR files. A WAR file is a compressed directory hierarchy, and actually is a Java "jar" file that meets additional requirements Tomcat lays down. To make a proper WAR file requires understanding the basics of this hierarchy; we describe these below, using the TomcatTest WAR file used in Phase 0 to illustrate.
You can look at the contents of TomcatTest. and WAR files in general, in a couple of ways:
By deploying the WAR; that action decompresses the WAR file and stores it (by default) to C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\TomcatTest.
Decompressing the WAR file yourself with the command line
jar -xvf TomcatTest.war
The -xvf switch means "expand, being verbose in telling us what is going on, the file that immediately follows." This action places the WAR's contents into the directory from which the command was run; that is, it's the "root directory," discussed below.
Decompress the TomcatTest WAR; refer to the resulting directory hierarchy as you follow the discussion below to see how WAR files are "laid out."
The directory hierarchy for a WAR must have the following structure:
The root directory (folder): the files and directories that make up the suite of programs, pages, etc. that together provide your servlet's functionality, along with descriptive information used to deploy your servlet via Tomcat. It has the same name as the WAR file; in our example, TomcatTest. Typically stored directly in the root directory are static web pages and public JSP files; html, css and jsp files are common. A file that must be directly accessible to the browser must be in this folder. Other directories and files can appear as needed; certain ones are almost always included, as discussed below.
All files and directories in TomcatTest, and any other file or folder in it except for the WEB-INF folder, are "visible" to the Web and can be accessed by issuing a URL that leads to that folder or file. For instance, http://localhost:8080/TomcatTest/index.html will show TomcatTest's index page; try it!.
root directory\WEB-INF: the Java classes, libraries, and source code that implement the dynamic content of your web application; it and its contents are not visible to the Web.
root directory\WEB-INF\class: the class files that make up the servlet; the browser will look here for the class filess to load and run. Note TomcatTest.class resides here.
root directory\WEB-INF\lib: libraries, such as jar files, needed when running the servlet's class files. You'll note that, since TomcatTest is a servlet, and it "talks to" a PostgreSQL database, we have the Java servlet and the postgreSQL JDBC jars in this file.
root directory\WEB-INF\sources: the source code files used in the development of the servlet; in this case, it's TomcatTest.java. TomcatTest.class is also here, a result of compiling TomcatTest.java; all class files needed for servlet operation need to be placed in the class folder.
the file root directory\web.xml that contains information Tomcat needs for deployment of the servlet; it must conform to Tomcat's requirements for the WAR to be acceptable to Tomcat. This file tells Tomcat the name the web page that hosts the servelet is to have, the names of the classes in the class folder that are part of the servlet, and the mapping between the directory in which the servlet code resides and the URL that will be used to access it. Open web.xml to get an idea of how this is done.
The easiest way to make a FabFlixs WAR file is to use the TomcatTest directory hierarchy as a starting place. Make a copy of the hierarchy and change its root directory name to your team name. Update web.xml to reflect the name of your servlet, the descriptive name that is to appear on the Tomcat management page, and so onwhat tags do what in this file is easy to determine from its comments and a bit of experimenting. Add and remove files as needed to contain your Phase 2 work. Compile your Java files (see the next paragraph), create a WAR (see the paragraph after that), tell Tomcat to deploy it (you use the same procedure as was used in Phase 0, except you give the name of your WAR) and then use a browser to access it (using the URL designations you gave in webinf.xml).
When you compile a java servlet program, you must include in the classpath the file servlet-api.jar. You will find this file in, among other places, the lib directory of the folder in which you installed Tomcat. The path is typically C:\Program Files\Apache Software Foundation\Tomcat 6.0\lib\servlet-api.jar. You will also need to include the postgreSQL JDBC jar you installed in Phase 0; if you have added it to your classpath, you need do nothing further. So, for example, to compile a Java program FabFlixs.java, with the JDBC jar already in the classpath, but the servlet jar not, you would issue the command (on one line)
javac -classpath "%CLASSPATH%;C:\Program Files\Apache Software Foundation\Tomcat 6.0\lib\servlet-api.jar" FabFlixs.java
jar -cvf filename.war .
Since deployed Tomcat directories are accessible, if you need to fix a bug or make a change to your code (and you probably will!) you can do it directly in the deployed directory; make the change, recompile the code, and, since it's already deployed; just reload it using the Tomcat reload command, and you're ready to test it. Don't forget to reload because, if you do, Tomcat will use the original file, not the modified one. This approach is much easier than fixing the problem in the original directory hierarchy, recompiling it there, making a new WAR file, unloading the existing servlet and deploying the new WAR file. But do be careful: if you corrupt the structure of the deployed directory, you will need to remove the existing servlet and make and deploy a new WAR.
To prepare for the demo, have the WAR file you turned stored on your demonstration machine; also have the postgreSQL server up and running. When the demo begins, we will ask you to deploy the WAR file via Tomcat.
Demonstrate the correctness, completeness and performance of your customer functions. Your task is to convince us, in no more than 15 minutes, that your work is well and completely done and the FabFlixs project is ready to move to phase 3.
Written for ICS185 Winter 2005 as "Project 2" by Chen Li.
Revised by Norman Jacobson for ICS185 Spring 2005 by Norman Jacobson, March 2005.
Revised by Norman Jacobson to clarify some requirements, update links, and to add to
and reorganize the information about Tomcat, March 2007.
Incorporates some of information added to the Winter 2007 version of "Project 2" by Chen Li and Shengyue Ji.
Revised to include more detail and a clearer discussion on sale quantity and shipping
address, and to reflect they are now stored in the sales table, by Norman Jacobson, September 2007.
Removed sorting by genres and stars within the movie list (too archane); now one genre
is selected before movies are displayed (rather than all movies listed in genre order);
login logic simplified; specs added for what to do if the movie or star poster is unavailable
or invalid, by Norman Jacobson, December 2007.
Correction of minor typos, by Norman Jacobson, September & October 2008.
Added READ.ME file requirement, by Norman Jacobson, December 2008.
Minor updates to reflect postgreSQL 8.3.7, by Norman Jacobson, March 2009.