将后台的数据展示在用户端的首页,并有分页功能,搜索价格等功能
一. 修改web目录下的index.jsp页面
让web目录下的index.jsp页面改为如下,只提供一个转发地址,让其实际访问的是cilent目录下的index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:forward page="/client/clientBookServlet?action=page"></jsp:forward>
二. 编写client目录下的index.jsp页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>首页</title>
<% //获取当前工程的路径
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<base href="<%=basePath%>">
</head>
<body>
<div align="center">
<%-- 如果用户还没有登录,显示登录和注册菜单--%>
<c:if test="${empty sessionScope.user}">
<a href="pages/user/login.jsp"><input type = "button" value = "登录"/></a>
<a href="pages/user/regist.jsp"><input type = "button" value = "注册"/></a>
</c:if>
<%-- 如果用户已经登录,显示欢迎用户、注销、后台管理--%>
<c:if test="${not empty sessionScope.user}">
欢迎${sessionScope.user.username}
<a href="userServlet?action=logout"><input type = "button" value = "注销"/></a>
<a href="pages/manager/manager.jsp"><input type = "button" value = "后台管理"/></a>
</c:if>
</div>
<div align="center">
<form action="client/clientBookServlet" method="get">
<input type="hidden" name="action" value="pageByPrice">
价格:<input id="min" type="text" name="min" value="${param.min}"/>元 — <input id="max" type="text" name="max" value="${param.max}"/>元 <input type="submit" value="查询"/>
</form>
<c:forEach items="${requestScope.page.items}" var="book">
<div>
<div>
<img src="${book.img}" width="150px"/>
</div>
<div>
<div class="book_name">
<span class="sp1">书名:</span>
<span class="sp2">${book.bookname}</span>
</div>
<div class="book_author">
<span class="sp1">作者:</span>
<span class="sp2">${book.author}</span>
</div>
<div class="book_price">
<span class="sp1">价格:</span>
<span class="sp2">${book.price}</span>
</div>
<div class="book_sales">
<span class="sp1">销量:</span>
<span class="sp2">${book.sale}</span>
</div>
<div class="book_amount">
<span class="sp1">库存:</span>
<span class="sp2">${book.stock}</span>
</div>
<div class="book_add">
<button>加入购物车</button>
</div>
</div>
</div>
</c:forEach>
</div>
<div align="center">
<%-- 如果当前页面是第一页,则不显示首页和上一页 --%>
<c:if test="${requestScope.page.pageNumber > 1}">
<a href = "client/clientBookServlet?action=page&pageNumber=1">首页</a>
<a href = "client/clientBookServlet?action=page&pageNumber=${requestScope.page.pageNumber-1}">上一页</a>
</c:if>
<%-- 页码输出的开始 --%>
<c:choose>
<%-- 情况1:如果总页码小于等于3,则显示页码的范围是:1 —— 总页码数 --%>
<c:when test="${requestScope.page.pageTotalNumber <= 3}">
<c:set var="begin" value="1"/>
<c:set var="end" value="${requestScope.page.pageTotalNumber}"/>
</c:when>
<%-- 情况2:如果总页码大于3 --%>
<c:when test="${requestScope.page.pageTotalNumber > 3}">
<c:choose>
<%-- 情况2.1:如果当前页码为前两页时,则显示页码的范围是:1 —— 3 --%>
<c:when test="${requestScope.page.pageNumber <= 2}">
<c:set var="begin" value="1"/>
<c:set var="end" value="3"/>
</c:when>
<%-- 情况2.2:如果当前页码为最后两页时,则显示页码的范围是:总页数减2 —— 最后一页 --%>
<c:when test="${requestScope.page.pageNumber >= requestScope.page.pageTotalNumber-2}">
<c:set var="begin" value="${requestScope.page.pageTotalNumber-2}"/>
<c:set var="end" value="${requestScope.page.pageTotalNumber}"/>
</c:when>
<%-- 情况2.3:如果当前页码为其他页码时,则显示页码的范围是:当前页码减1 —— 当前页码加1 --%>
<c:otherwise>
<c:set var="begin" value="${requestScope.page.pageNumber-1}"/>
<c:set var="end" value="${requestScope.page.pageNumber+1}"/>
</c:otherwise>
</c:choose>
</c:when>
</c:choose>
<c:forEach begin="${begin}" end="${end}" var="i">
<c:if test="${i == requestScope.page.pageNumber}">
【${i}】
</c:if>
<c:if test="${i != requestScope.page.pageNumber}">
<a href="client/clientBookServlet?action=page&pageNumber=${i}">${i}</a>
</c:if>
</c:forEach>
<%-- 页码输出的结束 --%>
<%-- 如果当前页面已经是最后一页,则不显示下一页和末页 --%>
<c:if test="${requestScope.page.pageNumber < requestScope.page.pageTotalNumber}">
<a href = "client/clientBookServlet?action=page&pageNumber=${requestScope.page.pageNumber+1}">下一页</a>
<a href = "client/clientBookServlet?action=page&pageNumber=${requestScope.page.pageTotalNumber}">末页</a>
</c:if>
共${requestScope.page.pageTotalNumber}页,${requestScope.page.dataTotalCount}条记录,到第<input value="${param.pageNumber}" id="page_input">页
<input type="button" value="确定" onclick="location.href='client/clientBookServlet?action=page&pageNumber='+document.getElementById('page_input').value">
<!--location.href表示链接的路径,document.getElementById('page_input').value表示获取输入框中的内容-->
</div>
</body>
</html>
三. 编写ClientBookServlet程序
page方法用来显示分页数据, pageByPrice方法用来显示根据价格区间搜索后的分页数据
package server.web;
import server.pojo.Book;
import server.pojo.Page;
import server.service.BookService;
import server.service.impl.BookServiceImpl;
import server.utils.WebUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/client/clientBookServlet")
public class ClientBookServlet extends BaseServlet{
private BookService bookService = new BookServiceImpl();
protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的参数pageNumber和pageSize
int pageNumber = WebUtils.parseInt(req.getParameter("pageNumber"),1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
//调用BookService类的Page(pageNumber,pageSize)方法
Page<Book> page = bookService.page(pageNumber,pageSize);
//保存Page对象到Request域中
req.setAttribute("page",page);
//重定向到pages/client/index.jsp页面
req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);
}
protected void pageByPrice(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的参数pageNumber和pageSize
int pageNumber = WebUtils.parseInt(req.getParameter("pageNumber"),1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
int min = WebUtils.parseInt(req.getParameter("min"),0);
int max = WebUtils.parseInt(req.getParameter("max"),Integer.MAX_VALUE);
//调用BookService类的Page(pageNumber,pageSize)方法
Page<Book> page = bookService.pageByPrice(pageNumber,pageSize, min, max);
//保存Page对象到Request域中
req.setAttribute("page",page);
//重定向到pages/client/index.jsp页面
req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);
}
}
四. 添加其他额外方法
1.在BookService接口中添加pageByPrice方法
public Page<Book> pageByPrice(int pageNumber, int pageSize, int min, int max);
2.在BookServiceImpl类中实现pageByPrice方法
@Override
public Page<Book> pageByPrice(int pageNumber, int pageSize, int min, int max) {
Page<Book> page = new Page<>();
//设置每页显示的数量
page.setPageSize(pageSize);
//求总的记录数
Integer dataTotalCount = bookDao.queryDataTotalCountByPrice(min,max);
//设置总记录数
page.setDataTotalCount(dataTotalCount);
//求总页码数
Integer pageTotalNumber = dataTotalCount / pageSize;
if(dataTotalCount % pageSize > 0){
pageTotalNumber += 1;
}
//设置总页码数
page.setPageTotalNumber(pageTotalNumber);
//设置当前页码
page.setPageNumber(pageNumber);
//求当前页数据的开始索引
int begin = (page.getPageNumber() - 1) * pageSize;
//求当前页的数据
List<Book> items = bookDao.queryPageItemsByPrice(begin,pageSize,min,max);
//设置当前页的每一个数据
page.setItems(items);
return page;
}
3.在BookDao接口中添加以下两个方法
public Integer queryDataTotalCountByPrice(int min, int max);
public List<Book> queryPageItemsByPrice(int begin, int pageSize, int min, int max);
4.在BookDaoImpl中实现上述方法
@Override
public Integer queryDataTotalCountByPrice(int min, int max) {
String sql = "select count(*) from book where price between ? and ?";
Number count = (Number) querySingleValue(sql,min,max);
return count.intValue();
}
@Override
public List<Book> queryPageItemsByPrice(int begin, int pageSize, int min, int max) {
String sql = "select * from book where price between ? and ? order by price limit ?,?";
return queryList(Book.class,sql,min,max,begin,pageSize);
}