页面头部登陆前后不同状态
登陆前后主要区别体现在首页的头部:
登录前,右上角最后一个为新用户注册,下面并无登陆者信息:
登陆后,右上角最后一个为退出登录,下面同时显示登陆者信息:
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的双层支持,在标签内需要引入轮播图的实现
js
以及css
代码。在标签内引用并添加展示图片,前端知识也挺多的暂时放着,怕扎进去出不来了。
<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减去一个时间段后的日期。