項目搭建 1.導入原型 只有前端頁面,但沒有後端代碼的項目。即一個只有頁面但沒有功能的項目! 導入原型: 2.前臺需求分析 前臺是針對會員購書,而後臺是管理員管理系統並完成售書。 2.1 前臺主頁 /index.jsp使用<jsp:forward>轉發到/jsps/main.jsp,、main.js ...
項目搭建
1.導入原型
只有前端頁面,但沒有後端代碼的項目。即一個只有頁面但沒有功能的項目!
導入原型:
- 創建一個web項目,命名為goods;
- 把原型的webroot和src兩個目錄copy到goods中,覆蓋原有的文件夾;
- 把goods發佈到tomcat上,打開瀏覽器,訪問主頁。
2.前臺需求分析
前臺是針對會員購書,而後臺是管理員管理系統並完成售書。
2.1 前臺主頁
/index.jsp使用<jsp:forward>轉發到/jsps/main.jsp,、main.jsp中只有一個<table>,結構如下:
main.jsp
<table>中各個部分使用的是<iframe>完成的框架頁。
(1):/jsps/top.jsp;
(2):/jsps/left.jsp;
(3):/jsps/searchj.jsp;
(4):/jsps/body.jsp
在(1)、(2)、(3)部分都存在超鏈接或表單,無論點擊哪個超鏈接(或提交表單)都會在(4)部分顯示
2.2 模塊劃分
系統分為如下模塊:
- 用戶模塊
- 分類模塊
- 圖書模塊
- 購物車模塊
- 訂單模塊
2.3前臺用戶模塊
用戶模塊功能有:
- 註冊
- 激活
- 登錄
- 修改密碼
- 退出
2.4前臺分類模塊
分類模塊功能有:
- 顯示所有分類;
2.5前臺圖書模塊
- 前臺圖書模塊功能有:
- 分頁查看指定分類的圖書;
- 分頁查看指定名稱的圖書;
- 分頁查看指定條件的圖書;
- 查看圖書詳細信息。
2.5購物車模塊
- 購物車模塊功能有:
- 向車中添加條目;
- 查看我的購物車;
- 修改條目數量;
- 刪除條目;
- 批量刪除條目;
2.6前臺訂單模塊
前臺訂單模塊功能有:
- 生成訂單;
- 查看我的訂單;
- 查看訂單詳細信息;
- 取消訂單;
- 確認收貨;
- 支付訂單;
3.後臺需求分析
後臺是管理員管理系統,以售書功能。
3.1 後臺主頁
與前臺主頁一樣,使用框架頁。
3.2管理員模塊
管理員模塊功能有:
- 管理員登錄;
- 管理員退出;
3.3後臺分類管理
後臺分類管理功能有:
- 查看所有分類;
- 添加一級分類;
- 添加二級分類;
- 編輯一級分類;
- 編輯二級分類;
- 刪除一級分類;
- 刪除二級分類;
3.4後臺圖書管理
後臺圖書管理功能有:
- 分頁查看指定分類的圖書;
- 分頁查看指定條件的圖書;
- 添加新圖書;
- 編輯圖書;
- 刪除圖書;
3.5 後臺訂單管理
後臺訂單管理功能有:
- 分頁查看所有訂單;
- 分頁查看指定狀態的訂單;
- 查看訂單詳細信息;
- 訂單發貨;
- 取消訂單;
4數據模型設計
根據需求分析,得到如下實體:
- User:會員;
- Category:圖書分類;
- Book:圖書;
- CartItem:購物車條目;
- Order:訂單;
- OrderItem:訂單條目;
- Admin:管理員。
4.1 t_user表
列名 |
列類型 |
描述 |
uid |
char(32) |
主鍵 |
loginname |
varchar(50) |
會員登錄名 |
loginpass |
varchar(50) |
會員登錄密碼 |
|
varchar(50) |
郵箱地址 |
status |
boolean |
是否已激活 |
activationCode |
char(64) |
激活碼 |
4.2 t_category表
列名 |
列類型 |
描述 |
cid |
char(32) |
主鍵 |
cname |
varchar(50) |
圖書分類名稱 |
pid |
char(32) |
外鍵,相對本表的cid,表示父分類id。 |
desc |
varchar(100) |
分類描述 |
orderBy |
int |
分類序號,用來排序。 |
4.3 t_book表
列名 |
列類型 |
描述 |
bid |
char(32) |
主鍵 |
bname |
varchar(200) |
圖書名稱 |
author |
varchar(50) |
圖書作者 |
price |
decimal(8,2) |
定價 |
currPrice |
decimal(8,2) |
當前價 |
discount |
decimal(3,1) |
折扣 |
press |
varchar(100) |
出版社 |
edition |
int |
版次 |
pageNum |
int |
頁數 |
wordNum |
int |
字數 |
printtime |
char(10) |
印刷時間 |
booksize |
int |
開本 |
paper |
varchar(50) |
紙質 |
cid |
char(32) |
所屬分類id |
image_w |
varchar(100) |
大圖路徑 |
image_b |
varchar(100) |
小圖路徑 |
orderBy |
int |
序號 |
4.4 t_cartitem表
列名 |
列類型 |
描述 |
cartItemId |
char(32) |
主鍵 |
quantity |
int |
數量 |
bid |
char(32) |
圖書id |
uid |
char(32) |
當前會員id |
orderBy |
int |
序號 |
4.5 t_order表
列名 |
列類型 |
描述 |
oid |
char(32) |
主鍵 |
ordertime |
char(19) |
下單時間 |
total |
decimal(10,2) |
合計金額 |
status |
int |
訂單狀態:1 未付款、2 未發貨、3 未收貨、4 交易成功、5 已取消 |
address |
varchar(1000) |
收貨地址 |
uid |
char(32) |
當前會員id |
4.6 t_orderitem
列名 |
列類型 |
描述 |
orderItemId |
char(32) |
主鍵 |
quantity |
int |
數量 |
subtotal |
decimal(8,2) |
金額小計 |
bid |
char(32) |
圖書id |
bname |
varchar(200) |
圖書名稱 |
currPrice |
decimal(8,2) |
當前價 |
image_b |
varchar(100) |
小圖路徑 |
oid |
char(32) |
所屬訂單id |
4.7 t_admin
列名 |
列類型 |
描述 |
adminId |
char(32) |
主鍵 |
adminname |
varchar(50) |
管理員登錄名 |
adminpwd |
varchar(50) |
管理員密碼 |
5項目框架
5.1導包
項目所需要導什麼包,要從項目所使用的工具來計算。本項目需要使用工具如下:
- c3p0;
- commons-beanutils;
- commons-dbutils;
- commons-fileupload;
- commons-fileupload.jar;
- javamail;
- Log4J;
- mysql-connector;
- itcast-tools。
5.2配置文件
本項目使用了C3P0資料庫連接池,所以需要在src下配置c3p0-config.xml文件。模板如下:
c3p0-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <c3p0-config> <default-config> <property name="jdbcUrl">jdbc:mysql://localhost:3306/goods</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password">123</property>
<property name="acquireIncrement">3</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">2</property> <property name="maxPoolSize">10</property> </default-config> </c3p0-config> |
5.3建包
包名的結構一般為:公司功能變數名稱.項目名.模塊名稱.分層名稱。本項目的包大致如下:
- cn.itcast.goods.user.domain;
- cn.itcast.goods.user.dao;
- cn.itcast.goods.user.service;
- cn.itcast.goods.user.web.servlet;
- cn.itcast.goods.category.doamin;
- cn.itcast.goods.category.dao;
- cn.itcast.goods.category.service;
- cn.itcast.goods.category.web.servlet;
- cn.itcast.goods.book.domain;
- cn.itcast.goods.book.service;
- cn.itcast.goods.book.web.servlet;
- cn.itcast.goods.cart.domain;
- cn.itcast.goods.cart.dao;
- cn.itcast.goods.cart.service;
- cn.itcast.goods.cart.web.servlet;
- cn.itcast.goods.order.domain;
- cn.itcast.goods.order.dao;
- cn.itcast.goods.order.service;
- cn.itcast.goods.order.web.servlet;
- cn.itcast.goods.web.filter;
- cn.itcast.goods.admin.admin.domain;
- cn.itcast.goods.admin.category.web.servlet;
- cn.itcast.goods.admin.book.web.servlet;
- cn.itcast.goods.admin.order.web.servlet。
5.4JQuery非同步請求
本項目的頁面中使用JQuery來完成表單的校驗,而且還使用了JQuery的AJAX。這裡簡單回顧一下使用JQuery發送非同步請求的過程。
使用JQuery發送非同步請求最為靈活的方法是ajax()方法,該方法只有一個參數,參數為一個JSON對象,下麵來看看這個對象的屬性。
- async:預設為true,表示發送非同步請求。
- beforeSend:函數類型。該函數會在發送請求前被調用,可以用來設置自定義的HTTP報頭。該函數有一個參數為XMLHttpRequest類型,我們可以使用它完成底層AJAX的設置,如果該函數返回false,那麼當前請求會被取消。
- cache:預設為true,表示是否在瀏覽器緩存中載入信息。當dataType為script時,該屬性為false。
- complete:函數類型,無論請求是否成功,當請求結束時調用它。該函數有兩個參數,function (XMLHttpRequest, textStatus)。
- contentType:預設為application/x-www-form-urlencoded,一般無需修改該屬性。
- data:請求參數,格式為{key1:val1,key2:val2…}。如果val為數組那麼會被轉換為多個參數,例如{key:[val1,val2]}轉換為key=val1&key=val2。
- dataType:可選值為xml、html、script、json、jsonp、text。表示伺服器的響應數據的類型。
- type:預設為GET,表示請求方式。POST和GET使用的比較多。
- url:請求的伺服器資源,可以是一個html、xml、jsp和Servlet等。
- success:請求成功調用的函數。函數形如fun(data,status),其中data為通過dataType進行了轉換的伺服器響應數據。
- error:請求失敗時調用的函數。函數形如fun(XMLHttpRequest, status, errorThrown) 。
常用屬性有6個:
- url:要請求的伺服器端地址
- dataType:伺服器返回數據的類型,我們通常用json;
- data:客戶端發送給伺服器的參數;
- type:請求方法,可以是GET或POST
- async:是否為非同步(如果為true,那麼是用兩個線程來完成,否則是一個線程)
- cache:客戶端是否緩存數據。
- success:成功是調用的方法。
例如:
<script type="text/javascript" src="<c:url value='/js/jquery-1.5.1.js'/>"></script> <script type="text/javascript"> $(function() [q1] { $("#btn").click([q2] function() { var name = $("#name").val(); if(name) { $.ajax[q3] ({ async: false, cache: false, type: "POST"[q4] , dataType: "json"[q5] , url[q6] : "<c:url value='/AjaxServlet'/>", data[q7] : {method: "findByName", name: name}, success[q8] : function(person) { $("#person").text(person.pid + ", " + person.name + ", " + person.age + ", " + person.birthday); } }); } }); }); </script> |
<body> 請輸入姓名:<input type="text" id="name" name="name"/> <input type="submit" value="查詢" id="btn"/> <div id="person"></div> </body> |
public class AjaxServlet extends BaseServlet { public String findByName[q9] (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name")[q10] ; PersonDao dao = new PersonDao(); try { Person person = dao.findByName(name); StringBuilder sb = new StringBuilder(); sb.append("{"); sb.append("\"pid\":").append("\"").append(person.getPid()).append("\","); sb.append("\"name\":").append("\"").append(person.getName()).append("\","); sb.append("\"age\":").append("\"").append(person.getAge()).append("\","); sb.append("\"birthday\":").append("\"").append(person.getBirthday()).append("\""); sb.append("}"); [q11] response.getWriter().print(sb);[q12] } catch (SQLException e) { throw new RuntimeException(e); } return null; } } |
6頁面結構
6.1目錄介紹
在WebRoot下有很多文件夾,下麵我們對這些文件夾進行介紹:
- adminjsps:後臺管理jsp頁面;
- bank_img:銀行圖片,線上支付時,會員需要選擇支付的網銀,這個頁面需要顯示這些圖片;
- book_img:每本書都要有大圖和小圖,圖書的圖片都在這個文件夾中;
- css:公共css樣式文件;
- images:按鈕圖片;
- jquery:jquery的源代碼;
- js:公共js腳本;
- jsps:前臺會員購書jsp頁面;
- menu:javascript小工具,在前臺首頁的左部就是使用的這個小工具來顯示圖書分類的。
6.2jsps目錄介紹
jsps目錄下是前臺頁面:
index.jsp中只有一條語句,使用<jsp:forward>標簽轉發到/jsps/main.jsp。而main.jsp頁面是框架頁,分為上、左、高級、中三個部分。分別對應:top.jsp、left.jsp、gj.jsp、body.jsp。
其中book、cart、order、user目錄中分別對應各自模塊的頁面;pager是分頁頁面,使用分頁的頁面會使用<%@include>指令包含分頁頁面。
js和css目錄下又分為book、cart、order、user目錄:
對應不同頁面的css和js文件。
7 添加過濾器
添加編碼過濾器!
web.xml
<filter> <filter-name>EncdoingFilter</filter-name> <filter-class>cn.itcast.filter.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>EncdoingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
[q1]這個的內容會在當前頁面被載入完成後執行,相同與<body>的onload事件。
[q2]給id為btn的元素添加click事件
[q3]發送非同步請求
[q4]請求方式為POST
[q5]伺服器返回的數據類型為json類型
[q6]請求的url為/AjaxServlet
[q7]請求參數有兩個,分別為method=findByName以及name=name
[q8]當請求成功後,會執行這個方法,其中參數person是由伺服器返回的json對象。
[q9]因為請求伺服器時指定method參數值為findByName,所以就會調用本方法
[q10]獲取name參數值
[q11]把Person對象轉換成json對象
[q12] 發送給客戶端