主要邏輯:
頁面頭部登陸前後不同狀態
登陸前後主要區別體現在首頁的頭部:
登錄前,右上角最後一個爲新用戶註冊,下面並無登陸者信息:
登陸後,右上角最後一個爲退出登錄,下面同時顯示登陸者信息:
jsp中實現原理:
<%
User user = (User) request.getSession().getAttribute("user");
if(null == user){
%>
| <a href="${pageContext.request.contextPath}/client/register.jsp">新用戶註冊</a>
<%
}else{
%>
| <a href="${pageContext.request.contextPath}/logout" onclick="javascript:return confirm_logout()">用戶退出</a>
<br><br><br>歡迎您: ${user.username}
<%
}
%>
可見騷氣的if語句分開顯示不同情況下的頁面內容,登陸前顯示新用戶註冊登陸後變爲退出登錄,onclick
屬性指向一個自定義函數,彈出一個確認退出的提示,在接受到確定之後才調用LogoutServlet
後直接銷燬Session
。值得注意在Session
獲取User
之前,要導包,不然js中不能識別該類。
<%@ page import="cn.itcast.itcaststore.entity.User"%>
除此之外,視有無登錄情況,頭部我的賬戶
會有變化,沒有登錄就會跳轉登錄界面
,已經登陸就會重定向到賬戶信息頁面
,除此之外,根據角色的不同,登陸後我的賬戶
也會有不同的目標頁面,普通用戶跳轉至home.jsp
,超級用戶跳轉至myAccount.jsp
後臺管理頁面,這一套邏輯由web.xml
映射的MyAccountServlet
完成。
<a href="${pageContext.request.contextPath}/myAccount">我的帳戶</a>
MyAccountServlet:
//在session中查找名爲“user”的會話
User user = (User) request.getSession().getAttribute("user");
//如果找到沒有名爲“user”的會話,說明用戶沒有登錄,此時跳轉到登錄頁面
if (user == null) {
response.sendRedirect(request.getContextPath() + "/client/login.jsp");
return;
}
//如果是超級用戶,進入到網上書城後臺管理系統;否則進入到普通用戶的賬戶信息頁面
if ("超級用戶".equals(user.getRole())) {
response.sendRedirect(request.getContextPath() + "/admin/login/home.jsp");
// return;
}else{
response.sendRedirect(request.getContextPath() + "/client/myAccount.jsp");
// return;
}
分類顯示圖書
menu_search.jsp
文件中分類欄:
<div id="divmenu">
<a href="${pageContext.request.contextPath}/showProductByPage?category=文學">文學</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=生活">生活</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=計算機">計算機</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=外語">外語</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=經營">經管</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=勵志">勵志</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=社科">社科</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=學術">學術</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=少兒">少兒</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=藝術">藝術</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=原版">原版</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=科技">科技</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=考試">考試</a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=生活百科">生活百科</a>
<a href="${pageContext.request.contextPath}/showProductByPage" style="color:#b4d76d">全部商品目錄</a>
</div>
在這個模塊裏,主要是調用了ShowProductByPageServlet
,內容邏輯如下:
// 1.定義當前頁碼,默認爲1
int currentPage = 1;
String _currentPage = request.getParameter("currentPage");
if (_currentPage != null) {
currentPage = Integer.parseInt(_currentPage);
}
// 2.定義每頁顯示條數,默認爲4
int currentCount = 4;
String _currentCount = request.getParameter("currentCount");
if (_currentCount != null) {
currentCount = Integer.parseInt(_currentCount);
}
// 3.獲取查找的分類
String category = "全部商品";
String _category = request.getParameter("category");
if (_category != null) {
category = _category;
}
// 4.調用service,完成獲取當前頁分頁Bean數據.
ProductService service = new ProductService();
PageBean bean = service.findProductByPage(currentPage, currentCount,
category);
// 將數據存儲到request範圍,跳轉到product_list.jsp頁面展示
request.setAttribute("bean", bean);
request.getRequestDispatcher("/client/product_list.jsp").forward(request, response);
return;
主要指定三個參數category
、currentPage
、currentCount
來控制ProductService
的查詢結果並封裝到PageBean
中,然後在回到product_list.jsp
頁面讀取出來。
搜索查詢圖書
MenuSearchServlet
處理類在點擊提交搜索框時調用,該類主要是判斷搜索框是否爲默認值,空的話直接跳轉至顯示全部分類圖書
和上一個分類顯示模塊全部
分類重疊。若不爲空,就會直接調用ProductService
查詢結果封裝到PageBean
中,product_list.jsp
再調用,其實實質上這兩個搜索和分類用的是同一套底層調用類ProductDao
。一個是按分類查找,一個是按名字查找,返回結果都放在PageBean
中
MenuSearchServlet
中:
// 1.定義當前頁碼,默認爲1
int currentPage = 1;
String _currentPage = req.getParameter("currentPage");
if (_currentPage != null) {
currentPage = Integer.parseInt(_currentPage);
}
// 2.定義每頁顯示條數,默認爲4
int currentCount = 4;
//獲取前臺頁面搜索框輸入的值
String searchfield = req.getParameter("textfield");
//如果搜索框中沒有輸入值,則表單傳遞的爲默認值,此時默認查詢全部商品目錄
if("請輸入書名".equals(searchfield)){
req.getRequestDispatcher("/showProductByPage").forward(req, resp);
return;
}
//調用service層的方法,通過書名模糊查詢,查找相應的圖書
ProductService service = new ProductService();
PageBean bean = service.findBookByName(currentPage,currentCount,searchfield);
// 將數據存儲到request範圍,跳轉到product_search_list.jsp頁面展示
req.setAttribute("bean", bean);
req.getRequestDispatcher("/client/product_search_list.jsp").forward(req, resp);
輪播圖
輪播圖的實現需要CSS以及JS的雙層支持,在<head>
標籤內需要引入輪播圖的實現js
以及css
代碼。在<body>
標籤內引用並添加展示圖片,前端知識也挺多的暫時放着,怕扎進去出不來了。
<head>
<title>傳智書城</title>
<%-- 導入css --%>
<link rel="stylesheet" href="${pageContext.request.contextPath}/client/css/main.css" type="text/css" />
<!-- 導入首頁輪播圖css和js腳本 -->
<link type="text/css" href="${pageContext.request.contextPath }/client/css/autoplay.css" rel="stylesheet" />
<script type="text/javascript" src="${pageContext.request.contextPath }/client/js/autoplay.js"></script>
</head>
<!-- 圖書商場首頁輪播圖 start -->
<div id="box_autoplay">
<div class="list">
<ul>
<li><img src="${pageContext.request.contextPath }/client/ad/index_ad1.jpg" width="900" height="335" /></li>
<li><img src="${pageContext.request.contextPath }/client/ad/index_ad2.jpg" width="900" height="335" /></li>
<li><img src="${pageContext.request.contextPath }/client/ad/index_ad3.jpg" width="900" height="335" /></li>
<li><img src="${pageContext.request.contextPath }/client/ad/index_ad4.jpg" width="900" height="335" /></li>
<li><img src="${pageContext.request.contextPath }/client/ad/index_ad5.jpg" width="900" height="335" /></li>
</ul>
</div>
</div>
公告展示
<body>
<jsp:forward page="ShowIndexServlet"></jsp:forward>
</body>
在WebContent根目錄
下的index.jsp
文件中,只是調用一個ShowIndexServlet
其他什麼都沒做,他是怎麼初始化公告內容和訂單內容的呢?
//查詢最近一條公告,傳遞到index.jsp頁面進行展示
NoticeService nService = new NoticeService();
Notice notice = nService.getRecentNotice();
req.setAttribute("n", notice);
//請求轉發
req.getRequestDispatcher("/client/index.jsp").forward(req, resp);
可以看到,ShowIndexServlet
裏面getRecentNotice()
獲得一個最近公告的方法,返回的Notice
被命名爲n
放進了請求中,所以在WebContent/client/index.jsp
中可以直接通過EL表達式獲得該對象。
<td width="485" height="100%">${n.details }</td>
本週熱賣推薦
首頁界面關於這部分一直是空白,不知出了什麼bug。
//查詢本週熱銷的兩條商品,傳遞到index.jsp頁面進行展示
ProductService pService = new ProductService();
List<Object[]> pList = pService.getWeekHotProduct();
for(Object[] os:pList){
for(Object o:os){
System.out.println(o);
}
System.out.println("---------------------");
}
req.setAttribute("pList", pList);
//請求轉發
req.getRequestDispatcher("/client/index.jsp").forward(req, resp);
ShowIndexServlet
裏面,關於初始化熱賣商品是這樣描述,我們到ProductService
的getWeekHotProduct()
裏面看看,ProductService
裏面只是調用了ProductDao
的一個getWeekHotProduct()
方法,我們再進去看看:
//前臺,獲取本週熱銷商品
public List<Object[]> getWeekHotProduct() throws SQLException {
String sql = "SELECT products.id,products.name, "+
" products.imgurl,SUM(orderitem.buynum) totalsalnum "+
" FROM orderitem,orders,products "+
" WHERE orderitem.order_id = orders.id "+
" AND products.id = orderitem.product_id "+
" AND orders.paystate=1 "+
" AND orders.ordertime > DATE_SUB(NOW(), INTERVAL 7 DAY) "+
" GROUP BY products.id,products.name,products.imgurl "+
" ORDER BY totalsalnum DESC "+
" LIMIT 0,2 ";
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
return runner.query(sql, new ArrayListHandler());
}
考驗SQL功底的時候了,這條語句的意思是說:orderitem,orders,products三表關聯查詢,在訂單子項從屬的訂單id和訂單的id同一、商品id和訂單子項的商品id同一、訂單的支付狀態爲1、訂單提交的時間爲7天之內的條件下,以商品id、商品name、商品imgurl分組顯示查詢結果,以銷量降序排列,只顯示前3條。
可能是因爲數據庫內未存在已支付狀態的訂單,符合不了條件纔沒有結果。
limit是mysql的語法:
select * from table limit m,n
其中m是指記錄開始的index,從0
開始,表示第一條記錄
n
是指從第m+1
條開始,取n
條。
select * from tablename limit 2,4
即取出第3條至第6條,4條記錄
DATE_SUB(d,INTERVAL expr type)
函數返回起始日期d減去一個時間段後的日期。