【JAVA EE#4】【傳智書城·源碼閱讀】首頁邏輯:頁面頭部登陸前後不同狀態+分類顯示圖書+搜索查詢圖書+輪播圖+本週熱賣推薦+公告展示

主要邏輯:
在這裏插入圖片描述

頁面頭部登陸前後不同狀態
登陸前後主要區別體現在首頁的頭部:
登錄前,右上角最後一個爲新用戶註冊,下面並無登陸者信息:
在這裏插入圖片描述
登陸後,右上角最後一個爲退出登錄,下面同時顯示登陸者信息:
在這裏插入圖片描述
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;

主要指定三個參數categorycurrentPagecurrentCount來控制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裏面,關於初始化熱賣商品是這樣描述,我們到ProductServicegetWeekHotProduct()裏面看看,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減去一個時間段後的日期。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章