e-commerce website
TRANSCRIPT
2
Table of Contents INTRODUCTION 4
APPLICATION DESIGN 4 WEBSITE WIREFRAME DIAGRAMS 4 INDEX PAGE 4 CATEGORY PAGE 5 CART PAGE 5 CHECKOUT PAGE 6 CONFIRMATION PAGE 6 DEVELOPMENT PROCESS 7 FRONT-‐END DEVELOPMENT 7 WEB APPLICATION PROJECT STRUCTURE 7 DATA MODELING 7 ER DIAGRAM 8
TECHNOLOGIES USED 8 HTML, CSS, AND JAVASCRIPT TECHNOLOGIES 8 SERVLET AND JAVASERVER PAGES (JSP) TECHNOLOGIES 9 ENTERPRISE JAVABEANS (EJB) TECHNOLOGY 9 JAVA PERSISTENCE API (JPA) 9 THE JAVASERVER PAGES STANDARD TAG LIBRARY (JSTL) 9 JAVA DATABASE CONNECTIVITY (JDBC) 9
PAGE VIEWS AND CONTROLLER SERVLET 9
DATABASE CONNECTIVITY 10 ADDING SAMPLE DATA 10 CONNECTION POOL AND DATA SOURCE 10
ENTITY CLASSES AND SESSION BEANS 11 MVC DIAGRAM 11 ENTITY CLASSES 11 SESSION BEANS 11
SESSION MANAGEMENT 11
SESSION DATA HANDLING 11
CLIENT AND SERVER-‐SIDE VALIDATION 12 CLIENT SIDE 12 SERVER SIDE 12
USE CASE SCENARIO 12
TESTING 13 TEST PLAN 13 TEST RESULTS 13
3
CONCLUSION 14
REFRENCES 14
SCREEN SHOTS 15
SOURCE CODE 28 INDEX.JSP 28 CART.JSP 28 CATEGORY.JSP 30 CHECKOUT.JSP 31 CONFIRMATION.JSP 33 ECOMMERCE.CSS 35 HEADER.JSPF 41 FOOTER.JSPF 44 CONTROLLERSERVLET 44 WEB.XML 51
4
Introduction
This is the Website design for a Software Selling company called “SoftwareForYou”, the company is a retailer for companies like Microsoft, Apple, Adobe and some Antivirus companies. The website is designed for the customers who wish to purchase software online, so it basically includes a list of softwares available and a shopping cart which will store the items until the customer procedes for checkout. A Database is used to store all the data which is used or stored by the website.
Application Design
Website Wireframe Diagrams Wireframe is a Rough Sketch of the website which is to be designed. This particular website was designed based on the following diagrams:
Index Page
7
Development Process The development process started with Designing the website and its data model, Moreover the whole data flow had to be decided, and how the user interaction will look like.
Front-‐end development This part of the design process included designing the basic sctructure of the website and all the included pages so that the website is easy to navigate and use, I had to keep in mind different usability issues which are important to a web designer, as the design of the website is the part that interacts with the user. Some of the major issues are considered such as the response time of the website and overall simplicity of the website, to facilitate low user frustration and higher throughput of the website.
Web application project structure The Web application was designed using HTML and CSS , To give the website a vast cross browser compatibility, The Structure of the project is :
Location Files
Ecommerce/Web Pages Contains Web pages Ecommerce/Web Pages/css Contains Stylesheet Ecommerce/Web Pages/img Contains Images Ecommerce/Web Pages/js Contains Java Script Ecommerce/Web Pages/jspf Contains Header and Footer
Code Snippets Ecommerce/Web Pages/test Contains Test Code and Test files Ecommerce/Web Pages/index.jsp Contains Index file (Default
Page) Ecommerce/Source Packages/cart Contains Cart Servlet Ecommerce/Source Packages/controller Contains Controller Servlet Ecommerce/Source Packages/entity Contains Entity Servlets Ecommerce/Source Packages/filter Contains Timeout Servlet Ecommerce/Source Packages/session Contains Session facades Ecommerce/Source Packages/validate Contains Validation Servlets
Data modeling Date model defines different entities of a database and their structure, how they connect and relate to each other. The first process includes identifying these entities from the use case scenario. The Entities that were recognized for this scenario are :
8
• Customer • Category • Product • Order
By using these entities the ER diagram was created.
ER Diagram
Technologies Used
HTML, CSS, and JavaScript technologies HTML is used by all the jsp pages, to support a very wide range of browsers. As browsers are able to read and convert them into visible web pages so it is important for the jsp pages to give their output in html. CSS styling sheet is also used in this web application to give style to different elements in each page. It also defines the body and overall layout of the webpage. Javascript is basically used during the client side validation of the web application, which includes using a validation plugin in the Jquery core library jquery-‐1.4.2.js
9
Servlet and JavaServer Pages (JSP) technologies All the pages of this website are designed on JSP, the user interface mostly is developed using JSP, This gives a very easy to design environment to develop a website, as it is very easy to use as compared to html coding. Servlets are also used in the website to get the requests from the jsp pages, and reply them with appropriate response. We are using two servlets named “Controllerservlet” and “AdminServlet” to process the request and give response to the jsp pages.
Enterprise JavaBeans (EJB) technology This technology was used in this website when the Entity classes were created, these entity classes represent each table of the database, so when any data has to be stored an instance of a entity class will be created and the data will be passed to Entity class, then it will be written to the database.
Java Persistence API (JPA) Java persistence was helpful in generating the Session beans from the Entity classes, JPA is helpful to the controller servlet because it provides a standard Query language called JPQL (Java persistence Querry Language). This helps the application to remain portable across many database vendors.
The JavaServer Pages Standard Tag Library (JSTL) JSTL is used in this website to populate the data tables of different categories and different products, The JSTL <for: each> loop is used for such processes, it is much easier to use than to manually give each element database link and populate a product table.
Java Database Connectivity (JDBC) JDBC is used in this website as the core API form which MySql Database is accessed, it provides a standard syntax for connectivity to each database, First the Database was created and then JDBC drivers were installed. Then Testing was also done so that the database data can be viewed from the jsp page.
Page Views and Controller Servlet
Page views are the pages which will be used by the customer to display the content in any browser, They are the html files which will be rendered by the browsers, The servlets are the java files which are processed by the server and gives its results to the jsp files which then display these results as html to the user. First all the jsp files are created, like index.jsp, cart.jsp, category.jsp, checkout.jsp, confirmation.jsp. these files represent all the pages user needs to visit for performing a purchase from this website.
10
The index.jsp has to be made at index.jsp and all the other files will be kept inside the view folder of “WEB-‐INF”, because the index.jsp is the file that server looks for at the webroot to start executing the website. In the webpages folder the CSS style sheet is also created to define the styles of different boxes which are used by every jsp file, it also stores the style data for the basic structure of the website. The controller servlet is a file that will control every request and response from the user that is from the jsp files. Every request is received by the controllerservlet.java file and processed by the server side, then the response is given back to the page.
Database connectivity
Database connectivity is required by the website because every data from the website including the product list and categories are read from the database and it also stores the customer information and purchase order details which is given by the customer when a product is ordered.
Adding Sample Data Sample data is added by using the gui provided by the net beans IDE for the MySQL database, This data includes defining categories and products for the category and product list in the website. The Four Categories Includes :
• Microsoft • Adobe • Apple • Antivirus
All the products related the these companies are also added in the database.
Connection Pool and Data Source This is the process in which we will connect the database to the website through the glassfish server. This connectivity is done with the help of Java Database Connectivity (JDBC) API. Whenever we need to access the database by a java application, we have to first setup a connection pool. This pool maintains a pool of connection to the database, which contains reusable connection to a particular database. A Data source is a JDBC Data Resource which provides the application a way of connecting to the database. The application is provided a connection from the
11
connection pool by looking into the Java Naming Directory Interface (JNDI). The connection pool, which is associated with a particular data source from which the connections are provided.
Entity Classes and Session Beans
MVC Diagram
Entity Classes Entity classes are generated using the “Entity classes from Database” wizard. Each entity class is like a table in the database, Instances of the entity classes can be created to represent the records that need to be saved. For example the and Instance of the entity class Customer is made by the Ordermanager class, which uses it to save customer data to the database.
Session Beans Session beans represent the encapsulation of the business logic of the application, these can be represent as either façade classes that use CRUD(Create Read Update Delete) to access the database.
Session Management
The shopping cart facility needs to remember the data of the cart, as user navigates through the website, Therefore we as a developer need to take care of cart data generated by the user so that it retains the information after the user navigates to other pages, another reason to manage this data is so that when more than one user updates the cart the information from both the users should not be confused with each other.
Session Data Handling
12
To implement this we need to create a session when user starts the browsing and maintain the session until the browser is closed, We use the HttpSession interface to do this and we also create two servlets which store the shopping cart data temporarily for each session.
Client and server-‐side validation
Client Side Form Validation or Client Side validation is a method of checking a form, so that we can validate the inputs which are provided by the customer before they are sent to the server for checking. This also prevents users to input malicious content which would adversely affect the server. For this application we are using a Jquery Plugin “jquery.validate.js” . Which is referenced in Header.jspf so that the validation plugin can be directly referenced in the checkout.jsp
Server Side Server side validation is done to check if the data is in correct format for further processing and if the data is ready to be stored in the database. The server side validation in this website is done by the help of Validator class, The ControlerServlet creates an object of validator class and calls the validateForm method for the user data.
Use Case Scenario
The customer goes to the website and visits the home page, Then selects a product category, After the category selection customer adds a product to the shopping cart. Customer browses through different categories and selects several other products to the cart. Then customer clicks on “View Cart” option and updates the product quantities in the view cart page. Customer then checks the contents of the cart and verifies the costs of the items. Then customer reaches the checkout page, Then He or She checks to total cost of the order which includes the delivery charge, Then the customer fills in the personal data and submits the details. Then the customer is redirected to the confirmation page which provides the customer with a unique id and details about the purchased order.
13
Testing
Test Plan A list of user-‐initiated requests to the server, based on the given use-‐case, might look something like the following:
Use-Case Server Request
Welcome page is visited by the customer /Ecommerce/
Product category is selected /Ecommerce/category
Customer browses through products and selects the products he or she needs
/Ecommerce/addToCart
Customer selects a different category and continues /Ecommerce/category
Customer adds different items to cart /Ecommerce /addToCart
/Ecommerce/addToCart
“View Cart” Option is selected /Ecommerce /viewCart
Quantities of different products are updated. /Ecommerce/updateCart
Shopping cart is validated and checked by the customer and customer proceeds to the checkout page
/Ecommerce/checkout
Then the customer checks the total amount and fills in his personal details and bank details.
/Ecommerce/purchase
The order is processed and customer is taken to a confirmation page. The confirmation page provides a unique reference number for tracking the customer order, as well as a summary of the order.
(n/a)
Test Results These are the test results for the heap generated during the Runtime of the web application.
14
Conclusion
With the number of website currently developed, it is necessary to learn these new technologies which enable easy and reliable website development. This website introduced me to many new technologies like JSP and Servlets, I also learned to use MySql and JDBC Drivers for my web application connectivity. I also learned about Business Data implementation which takes place within high end business web applications, I was also introduced to Design Patterns like MVC in a new perspective. A website can be valuable to any business because it represents the online presence of the business and attracts user from the internet. So, Websites should be planned developed and promoted in a proper way.
Refrences
Singh, I, Johnson, M. (2002). Designing Enterprise Applications with the J2EE Platform . London: Addison-Wesley. odesido, I. (2009). What is front-end development?. Available: http://www.theguardian.com/help/insideguardian/2009/sep/28/blogpost?commentpage=1. Last accessed 20th Apr 2014. Hall, M, Brown, L. (2004). Core Servlets and JavaServer Pages. 2nd ed. California: Sun Microsystem Press. Panda, D, Rahman, R, Derek Lane (2007). EJB 3 in Action. New York: Manning Publications Company
28
Source Code
Following is the source code for the important files:
Index.jsp <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%> <div id="indexLeftColumn"> <div id="welcomeText"> <h1>Welcome to SoftwareForYou</h1> <p>We provide you the best softwares in a very reasonable price. Softwares from all the major companies are available.</p> </div> </div> <div id="indexRightColumn"> <c:forEach var="category" items="${categories}"> <div class="categoryBox"> <a href="category?${category.id}"> <span class="categoryLabelText">${category.name}</span> <%-‐-‐<img src="img/categories/bakery.jpg" width="210" height="174" alt="bakery"/> -‐-‐%> <img src="${initParam.categoryImagePath}/${category.name}.png" alt="${category.name}"> </a> </div> </c:forEach> </div>
cart.jsp <div id="singleColumn"> <c:choose> <c:when test="${cart.numberOfItems > 1}"> <p>Your shopping cart contains ${cart.numberOfItems} items.</p> </c:when> <c:when test="${cart.numberOfItems == 1}"> <p>Your shopping cart contains ${cart.numberOfItems} item.</p> </c:when> <c:otherwise> <p>Your shopping cart is empty.</p> </c:otherwise> </c:choose> <div id="actionBar"> <%-‐-‐ clear cart widget -‐-‐%> <c:if test="${!empty cart && cart.numberOfItems != 0}">
29
<a href="viewCart?clear=true" class="bubble hMargin">clear cart</a> </c:if> <%-‐-‐ continue shopping widget -‐-‐%> <c:set var="value"> <c:choose> <%-‐-‐ if 'selectedCategory' session object exists, send user to previously viewed category -‐-‐%> <c:when test="${!empty selectedCategory}"> category </c:when> <%-‐-‐ otherwise send user to welcome page -‐-‐%> <c:otherwise> index.jsp </c:otherwise> </c:choose> </c:set> <a href="${value}" class="bubble hMargin">continue shopping</a> <%-‐-‐ checkout widget -‐-‐%> <c:if test="${!empty cart && cart.numberOfItems != 0}"> <a href="checkout" class="bubble hMargin">proceed to checkout ➟</a> </c:if> </div> <c:if test="${!empty cart && cart.numberOfItems != 0}"> <h4 id="subtotal">subtotal: £ ${cart.subtotal}</h4> <table id="cartTable"> <tr class="header"> <th>product</th> <th>name</th> <th>price</th> <th>quantity</th> </tr> <c:forEach var="cartItem" items="${cart.items}" varStatus="iter"> <c:set var="product" value="${cartItem.product}"/> <tr class="${((iter.index % 2) == 0) ? 'lightBlue' : 'white'}"> <td> <img src="${initParam.productImagePath}/${product.name}.png" alt="${product.name}"> </td> <td>${product.name}</td> <td> £ ${cartItem.total} <br> <span class="smallText">( £ ${product.price} / unit )</span> </td>
30
<td> <form action="updateCart" method="post"> <input type="hidden" name="productId" value="${product.id}"> <input type="text" maxlength="2" size="2" value="${cartItem.quantity}" name="quantity" style="margin:5px"> <input type="submit" name="submit" value="update"> </form> </td> </tr> </c:forEach> </table> </c:if> </div>
category.jsp <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%> <div id="categoryLeftColumn"> <c:forEach var="category" items="${categories}"> <c:choose> <c:when test="${category.name == selectedCategory.name}"> <div class="categoryButton" id="selectedCategory"> <span class="categoryText"> ${category.name} </span> </div> </c:when> <c:otherwise> <a href="category?${category.id}" class="categoryButton"> <span class="categoryText"> ${category.name} </span> </a> </c:otherwise> </c:choose> </c:forEach> </div>
31
<div id="categoryRightColumn"> <p id="categoryTitle">${selectedCategory.name}</p> <table id="productTable"> <c:forEach var="product" items="${categoryProducts}" varStatus="iter"> <tr class="${((iter.index % 2) == 0) ? 'lightBlue' : 'white'}"> <td> <img src="${initParam.productImagePath}/${product.name}.png" alt="${product.name}"> </td> <td> ${product.name} <br> <span class="smallText">${product.description}</span> </td> <td>£ ${product.price}</td> <td> <form action="addToCart" method="post"> <input type="hidden" name="productId" value="${product.id}"> <input type="submit" name="submit" value="add to cart"> </form> </td> </tr> </c:forEach> </table> </div>
checkout.jsp <div id="singleColumn"> <h2>checkout</h2> <p>In order to purchase the items in your shopping cart, please provide us with the following information:</p> <form action="purchase" method="post"> <table id="checkoutTable"> <tr> <td><label for="name">name:</label></td>
32
<td class="inputField"> <input type="text" size="31" maxlength="45" id="name" name="name" value="${param.name}"> </td> </tr> <tr> <td><label for="email">email:</label></td> <td class="inputField"> <input type="text" size="31" maxlength="45" id="email" name="email" value="${param.email}"> </td> </tr> <tr> <td><label for="phone">phone:</label></td> <td class="inputField"> <input type="text" size="31" maxlength="16" id="phone" name="phone" value="${param.phone}"> </td> </tr> <tr> <td><label for="address">address:</label></td> <td class="inputField"> <input type="text" size="31" maxlength="45" id="address" name="address" value="${param.address}"> <br> Coventry <select name="cityRegion"> <c:forEach begin="1" end="10" var="regionNumber"> <option value="${regionNumber}" <c:if test="${param.cityRegion eq regionNumber}">selected</c:if>>${regionNumber}</option> </c:forEach> </select> </td> </tr> <tr> <td><label for="creditcard">credit card number:</label></td> <td class="inputField"> <input type="text" size="31" maxlength="19"
33
id="creditcard" name="creditcard" value="${param.creditcard}"> </td> </tr> <tr> <td colspan="2"> <input type="submit" value="submit purchase"> </td> </tr> </table> </form> <div id="infoBox"> <ul> <li>Next-‐day delivery is guaranteed</li> <li>A £ ${initParam.deliverySurcharge} delivery surcharge is applied to all purchase orders</li> </ul> <table id="priceBox"> <tr> <td>subtotal:</td> <td class="checkoutPriceColumn"> £ ${cart.subtotal}</td> </tr> <tr> <td>delivery surcharge:</td> <td class="checkoutPriceColumn"> £ ${initParam.deliverySurcharge}</td> </tr> <tr> <td class="total">total:</td> <td class="total checkoutPriceColumn"> £ ${cart.total}</td> </tr> </table> </div> </div>
confirmation.jsp <div id="singleColumn"> <p id="confirmationText"> <strong>Your order has been successfully processed and will be delivered within 24 hours.</strong> <br><br> Please keep a note of your confirmation number: <strong>${orderRecord.confirmationNumber}</strong> <br> If you have a query concerning your order, feel free to <a href="#">contact us</a>. <br><br> Thank you for shopping at the SoftwareForYou! </p>
34
<div class="summaryColumn" > <table id="orderSummaryTable" class="detailsTable"> <tr class="header"> <th colspan="3">order summary</th> </tr> <tr class="tableHeading"> <td>product</td> <td>quantity</td> <td>price</td> </tr> <c:forEach var="orderedProduct" items="${orderedProducts}" varStatus="iter"> <tr class="${((iter.index % 2) != 0) ? 'lightBlue' : 'white'}"> <td>${products[iter.index].name}</td> <td class="quantityColumn"> ${orderedProduct.quantity} </td> <td class="confirmationPriceColumn"> € ${products[iter.index].price * orderedProduct.quantity} </td> </tr> </c:forEach> <tr class="lightBlue"><td colspan="3" style="padding: 0 20px"><hr></td></tr> <tr class="lightBlue"> <td colspan="2" id="deliverySurchargeCellLeft"><strong>delivery surcharge:</strong></td> <td id="deliverySurchargeCellRight">£ ${initParam.deliverySurcharge}</td> </tr> <tr class="lightBlue"> <td colspan="2" id="totalCellLeft"><strong>total:</strong></td> <td id="totalCellRight">£ ${orderRecord.amount}</td> </tr> <tr class="lightBlue"><td colspan="3" style="padding: 0 20px"><hr></td></tr> <tr class="lightBlue"> <td colspan="3" id="dateProcessedRow"><strong>date processed:</strong> ${orderRecord.dateCreated} </td> </tr> </table> </div>
35
<div class="summaryColumn" > <table id="deliveryAddressTable" class="detailsTable"> <tr class="header"> <th colspan="3">delivery address</th> </tr> <tr> <td colspan="3" class="lightBlue"> ${customer.name} <br> ${customer.address} <br> Coventry ${customer.cityRegion} <br> <hr> <strong>email:</strong> ${customer.email} <br> <strong>phone:</strong> ${customer.phone} </td> </tr> </table> </div> </div>
ecommerce.css /* html tags */ body { font-‐family: Arial, Helvetica, sans-‐serif; width: 850px; text-‐align: center; margin: 20px auto; color: #444; } hr { border: 0; background-‐color: #333; height: 1px; } table { margin: 0 20px; border-‐spacing: 0; text-‐align: center; border: solid 1px #f5eabe; } a { color: inherit; text-‐decoration: underline; } a:hover { text-‐decoration: none } a:visited { color: inherit }
36
img { border: none } input, select { margin: 5px } li { margin: 10px 0 } label { line-‐height: 30px } /* general styles */ #main { background: #f7f7e9 } #singleColumn { margin: 20px 30px; text-‐align: left; } .lightBlue { background-‐color: #edf8f7 } .white { background-‐color: #fff } .bubble { font-‐weight: bold; background-‐color: #f5eabe; padding: 5px; color: inherit; } .hMargin { margin: 0 30px } .smallText { font-‐size: small } .reallySmallText { font-‐size: xx-‐small } .header { background-‐color: #c3e3e0; height: 30px; } /* styles for elements contained in the header, i.e., shopping cart widget, language toggle, and logo */ #header { width: 850px; height: 250px; background-‐image:url("../img/header_background.png"); background-‐repeat:no-‐repeat; background-‐position:right top; } #logo { float: left; margin-‐left: 30px; margin-‐top: -‐20px; } #logoText { float: left;
37
margin: 20px 0 0 70px; /* font styles apply to text within img alt attribute */ font-‐family: 'American Typewriter', Courier, monospace; font-‐size: 50px; color: #333; } #widgetBar { height: 50px; width: 850px; float: right; } #cart { position: absolute; margin: 5px 0 0 2px; } .horizontalMargin { margin-‐left: 28px; margin-‐right: 5px } #viewCart { text-‐align: left; width: 210px; } .headerWidget { width: 194px; margin: 20px 0; font-‐size: small; float: right; line-‐height: 25px; } /* footer styles */ #footer { height: 60px; width: 350px; clear: left; } #footerText { margin-‐top: 5px } #footerDivider { margin: 0 25px; width: 300px; } /* index page styles */ #indexLeftColumn { text-‐align: left; height: 400px; width: 350px; float: left; }
38
#indexRightColumn { text-‐align: left; height: 400px; width: 500px; float: left; } #welcomeText { margin: 30px 5px 0 30px; line-‐height: 1.4em; } .categoryBox { height: 176px; width: 212px; margin: 21px 14px 6px; float: inherit; } .categoryLabel { position: absolute; background-‐color: #fff; opacity: 0.7; height: 40px; width: 210px; margin: 2px; } .categoryLabelText { position: relative; line-‐height: 150%; font-‐size: x-‐large; margin: 3px 10px; } .categoryImage { padding: 1px; border:solid 1px #999; } /* category page styles */ #categoryLeftColumn { width: 185px; float: left; margin-‐top: 25px; padding-‐left: 15px; } #categoryRightColumn { margin-‐top: 10px; width: 650px; float: left; } .categoryButton { margin: 15px 22px; padding: 13px;
39
display: block; background-‐color: #d3ede8; } #selectedCategory { background-‐color: #b2d2d2; margin-‐left: 10px; width: 139px; } #categoryTitle { margin: -‐34px 180px 0 0; font-‐size: x-‐large; float: right; background-‐color: #f5eabe; padding: 7px; } .categoryText { line-‐height: 25px; font-‐size: x-‐large; } #productTable { width: 600px } #productTable tr { height: 90px } #productTable td { width: 145px } /* cart page styles */ #actionBar { margin: 30px; width: 750px; text-‐align: center; } #subtotal { margin: 40px 0 20px 430px } #cartTable { width: 750px } #cartTable td { width: 145px; height: 90px; } /* checkout page styles */ #checkoutTable { width: 405px; padding: 10px; background-‐color: #f5eabe; float: left; } #checkoutTable td { vertical-‐align: top; text-‐align: right; margin: 5px;
40
} .inputField { width: 190px } #infoBox { padding: 10px 25px 0 460px } #priceBox { padding: 10px; border: 1px solid #c3e3e0; background-‐color: #c3e3e0; } #priceBox td { text-‐align: right; padding: 5px; } .checkoutPriceColumn { width: 80px; font-‐weight: bold; } .total { border-‐top: 1px solid #444 } /* confirmation page styles */ #confirmationText { margin: 0 20px 20px; padding: 10px; background-‐color: #f5eabe; float: left; width:540px; } .summaryColumn { margin-‐top: 15px; width: 50%; float: left; } #orderSummaryTable { width: 100%; text-‐align: left; height: 200px; } #deliveryAddressTable { width: 70%; margin-‐left: 15%; text-‐align: left; height: 200px; } /* admin styles */ #adminLogo { float:left; margin-‐left: 30px; margin-‐top: -‐20px; }
41
#loginBox { width: 300px; margin: 0 auto; border: solid 1px #f5eabe; background-‐color: #f5eabe; border-‐radius: 4px; } #adminMenu { float: left; width: 180px; margin: 25px 5px 0 30px; border: solid 1px #f5eabe; background-‐color: #f5eabe; border-‐radius: 4px; } #adminMenu p { margin-‐left: 15px } #adminTable { width: 580px; float: left; background-‐color: #edf8f7; } .alignLeft { text-‐align: left } .selectedRow { background-‐color: #c3e3e0; cursor: pointer; } .noDecoration { text-‐decoration: none } .rigidWidth { width:200px } .embedded { margin: 0; border: none; }
header.jspf <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%-‐-‐ Set language based on user's choice -‐-‐%> <c:if test="${!empty language}"> <fmt:setLocale value="${language}" scope="session" /> </c:if> <%@page pageEncoding="UTF-‐8" contentType="text/html; charset=UTF-‐8"%> <!DOCTYPE HTML PUBLIC "-‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
42
<html> <head> <meta http-‐equiv="Content-‐Type" content="text/html; charset=UTF-‐8"> <link rel="stylesheet" type="text/css" href="css/ecommerce.css"> <link rel="shortcut icon" href="img/favicon.png"> <title>SoftwareForYou</title> </head> <body> <div id="main"> <div id="header"> <div id="widgetBar"> <div class="headerWidget"> [ © Arisoft ] </div> <%-‐-‐ checkout widget -‐-‐%> <div class="headerWidget"> <%-‐-‐ tests for the following: * if cart exists and is not empty * if the servlet path does not contain '/checkout' * if the requested view is not checkout * if the servlet path does not contain '/cart' * if the requested view is not cart <c:if test="${!empty sessionScope.cart}"> CART EXISTS AND IS NOT NULL </c:if> <BR> <c:if test="${sessionScope.cart.numberOfItems != 0}"> NUMBER OF ITEMS IN CART IS NOT 0 </c:if> <BR> <c:if test="${fn:contains(pageContext.request.servletPath,'/checkout')}"> SERVLET PATH CONTAINS '/checkout' </c:if> <BR> <c:if test="${requestScope['javax.servlet.forward.servlet_path'] ne '/checkout'}"> REQUEST IS NOT CHECKOUT </c:if> -‐-‐%> <c:if test="${!empty cart && cart.numberOfItems != 0 && !fn:contains(pageContext.request.servletPath,'/checkout') && requestScope['javax.servlet.forward.servlet_path'] ne '/checkout' && !fn:contains(pageContext.request.servletPath,'/cart') &&
43
requestScope['javax.servlet.forward.servlet_path'] ne '/cart'}"> <a href="checkout" class="bubble"> proceed to checkout ➟ </a> </c:if> </div> <%-‐-‐ shopping cart widget -‐-‐%> <div class="headerWidget" id="viewCart"> <img src="img/cart.gif" alt="shopping cart icon" id="cart"> <%-‐-‐ If 'numberOfItems' property doesn't exist, or if number of items in cart is 0, output '0', otherwise output 'numberOfItems' -‐-‐%> <span class="horizontalMargin"> <c:choose> <c:when test="${cart.numberOfItems == null}"> 0 </c:when> <c:otherwise> ${cart.numberOfItems} </c:otherwise> </c:choose> <%-‐-‐ Handle singular/plural forms of 'item' -‐-‐%> <c:choose> <c:when test="${cart.numberOfItems == 1}"> item </c:when> <c:otherwise> items </c:otherwise> </c:choose> </span> <c:if test="${!empty cart && cart.numberOfItems != 0 && !fn:contains(pageContext.request.servletPath,'/cart') && requestScope['javax.servlet.forward.servlet_path'] ne '/cart'}"> <a href="viewCart" class="bubble"> view cart </a> </c:if> </div> </div> <a href="index.jsp"> <img src="img/logo.png" id="logo" alt="Logo"> </a> <img src="img/logoText.png" id="logoText" alt="Text">
44
</div>
footer.jspf <div id="footer"> <br> <hr> <p id="footerText" class="smallText"> <a href="#">Privacy Policy</a> :: <a href="#">Contact</a> © 2014 SoftwareForYou</p> </div> </div> </body> </html>
controllerServlet package controller; import cart.ShoppingCart; import entity.Category; import entity.Product; import java.io.IOException; import java.util.Collection; import javax.ejb.EJB; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import session.CategoryFacade; import session.OrderManager; import session.ProductFacade; /** * * @author arijitroy */ @WebServlet (name="ControllerServlet", loadOnStartup = 1, urlPatterns = {"/category", "/addToCart", "/viewCart", "/updateCart", "/checkout", "/purchase", "/chooseLanguage"}) public class ControllerServlet extends HttpServlet { /**
45
* Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-‐specific error occurs * @throws IOException if an I/O error occurs */ /** @EJB private CategoryFacade categoryFacade; @EJB private ProductFacade productFacade; private Category selectedCategory; private Collection<Product> categoryProducts; private String surcharge; @Override public void init() throws ServletException { // store category list in servlet context getServletContext().setAttribute("categories", categoryFacade.findAll()); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userPath = request.getServletPath(); HttpSession session = request.getSession(); Category selectedCategory; Collection<Product> categoryProducts; // if category page is requested if (userPath.equals("/category")) { // TODO: Implement category request // get categoryId from request String categoryId = request.getQueryString(); if (categoryId != null) { // get selected category selectedCategory = categoryFacade.find(Short.parseShort(categoryId)); // place selected category in request scope request.setAttribute("selectedCategory", selectedCategory); // get all products for selected category categoryProducts = selectedCategory.getProductCollection(); // place category products in request scope request.setAttribute("categoryProducts", categoryProducts); } // if cart page is requested } else if (userPath.equals("/viewCart")) { // TODO: Implement cart page request
46
String clear = request.getParameter("clear"); if ((clear != null) && clear.equals("true")) { ShoppingCart cart = (ShoppingCart) session.getAttribute("cart"); cart.clear(); } userPath = "/cart"; // if checkout page is requested } else if (userPath.equals("/checkout")) { // TODO: Implement checkout page request ShoppingCart cart = (ShoppingCart) session.getAttribute("cart"); // calculate total cart.calculateTotal(surcharge); // forward to checkout page and switch to a secure channel // if user switches language } else if (userPath.equals("/chooseLanguage")) { // TODO: Implement language request } // use RequestDispatcher to forward request internally String url = "/WEB-‐INF/view" + userPath + ".jsp"; try { request.getRequestDispatcher(url).forward(request, response); } catch (Exception ex) { ex.printStackTrace(); } } **/ private String surcharge; @EJB private CategoryFacade categoryFacade; @EJB private ProductFacade productFacade; @EJB private OrderManager orderManager; @Override public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); // initialize servlet with configuration information surcharge = servletConfig.getServletContext().getInitParameter("deliverySurcharge");
47
// store category list in servlet context getServletContext().setAttribute("categories", categoryFacade.findAll()); } /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-‐specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userPath = request.getServletPath(); HttpSession session = request.getSession(); Category selectedCategory; Collection<Product> categoryProducts; // if category page is requested if (userPath.equals("/category")) { // get categoryId from request String categoryId = request.getQueryString(); if (categoryId != null) { // get selected category selectedCategory = categoryFacade.find(Short.parseShort(categoryId)); // place selected category in session scope session.setAttribute("selectedCategory", selectedCategory); // get all products for selected category categoryProducts = selectedCategory.getProductCollection(); // place category products in session scope session.setAttribute("categoryProducts", categoryProducts); } // if cart page is requested } else if (userPath.equals("/viewCart")) { String clear = request.getParameter("clear"); if ((clear != null) && clear.equals("true")) { ShoppingCart cart = (ShoppingCart) session.getAttribute("cart"); cart.clear(); } userPath = "/cart";
48
// if checkout page is requested } else if (userPath.equals("/checkout")) { ShoppingCart cart = (ShoppingCart) session.getAttribute("cart"); // calculate total cart.calculateTotal(surcharge); // forward to checkout page and switch to a secure channel // if user switches language } else if (userPath.equals("/chooseLanguage")) { // TODO: Implement language request } // use RequestDispatcher to forward request internally String url = "/WEB-‐INF/view" + userPath + ".jsp"; try { request.getRequestDispatcher(url).forward(request, response); } catch (Exception ex) { ex.printStackTrace(); } } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-‐specific error occurs * @throws IOException if an I/O error occurs */ /** @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userPath = request.getServletPath(); HttpSession session = request.getSession(); ShoppingCart cart = (ShoppingCart) session.getAttribute("cart"); // if addToCart action is called if (userPath.equals("/addToCart")) { // TODO: Implement add product to cart action // if user is adding item to cart for first time // create cart object and attach it to user session if (cart == null) { cart = new ShoppingCart(); session.setAttribute("cart", cart); }
49
// get user input from request String productId = request.getParameter("productId"); if (!productId.isEmpty()) { Product product = productFacade.find(Integer.parseInt(productId)); cart.addItem(product); } userPath = "/category"; // if updateCart action is called } else if (userPath.equals("/updateCart")) { // TODO: Implement update cart action // get input from request String productId = request.getParameter("productId"); String quantity = request.getParameter("quantity"); Product product = productFacade.find(Integer.parseInt(productId)); cart.update(product, quantity); userPath = "/cart"; // if purchase action is called } else if (userPath.equals("/purchase")) { // TODO: Implement purchase action userPath = "/confirmation"; } // use RequestDispatcher to forward request internally String url = "/WEB-‐INF/view" + userPath + ".jsp"; try { request.getRequestDispatcher(url).forward(request, response); } catch (Exception ex) { ex.printStackTrace(); } } **/ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userPath = request.getServletPath(); HttpSession session = request.getSession(); ShoppingCart cart = (ShoppingCart) session.getAttribute("cart"); // if addToCart action is called if (userPath.equals("/addToCart")) { // if user is adding item to cart for first time // create cart object and attach it to user session if (cart == null) { cart = new ShoppingCart(); session.setAttribute("cart", cart);
50
} // get user input from request String productId = request.getParameter("productId"); if (!productId.isEmpty()) { Product product = productFacade.find(Integer.parseInt(productId)); cart.addItem(product); } userPath = "/category"; // if updateCart action is called } else if (userPath.equals("/updateCart")) { // get input from request String productId = request.getParameter("productId"); String quantity = request.getParameter("quantity"); Product product = productFacade.find(Integer.parseInt(productId)); cart.update(product, quantity); userPath = "/cart"; // if purchase action is called } else if (userPath.equals("/purchase")) { // TODO: Implement purchase action if (cart != null) { // extract user data from request String name = request.getParameter("name"); String email = request.getParameter("email"); String phone = request.getParameter("phone"); String address = request.getParameter("address"); String cityRegion = request.getParameter("cityRegion"); String ccNumber = request.getParameter("creditcard"); int orderId = orderManager.placeOrder(name, email, phone, address, cityRegion, ccNumber, cart); } userPath = "/confirmation"; } // use RequestDispatcher to forward request internally String url = "/WEB-‐INF/view" + userPath + ".jsp"; try { request.getRequestDispatcher(url).forward(request, response); } catch (Exception ex) { ex.printStackTrace(); } }
51
}
web.xml <?xml version="1.0" encoding="UTF-‐8"?> <web-‐app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-‐instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-‐app_3_1.xsd"> <context-‐param> <description>Path of Product Images </description> <param-‐name>productImagePath</param-‐name> <param-‐value>img/products</param-‐value> </context-‐param> <context-‐param> <description>Path of product categories</description> <param-‐name>categoryImagePath</param-‐name> <param-‐value>img/categories</param-‐value> </context-‐param> <context-‐param> <description>delivery surcharge applied to all orders</description> <param-‐name>deliverySurcharge</param-‐name> <param-‐value>3.00</param-‐value> </context-‐param> <session-‐config> <session-‐timeout> 30 </session-‐timeout> </session-‐config> <jsp-‐config> <jsp-‐property-‐group> <description>header and footer settings</description> <url-‐pattern>/index.jsp</url-‐pattern> <url-‐pattern>/WEB-‐INF/view/*</url-‐pattern> <include-‐prelude>/jspf/header.jspf</include-‐prelude> <include-‐coda>/jspf/footer.jspf</include-‐coda> </jsp-‐property-‐group> </jsp-‐config> </web-‐app>