ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] > 分页单独拿出来讲解 # 步骤 1 : 效果 如图所示,每页显示5条数据 注: 没有分类图片是正常的,在接下来的知识点就会做增加图片功能了 ![](https://box.kancloud.cn/8ac4d1288627df3e2e0d2c25c4b4ba9f_1892x432.png) # 步骤 2 : Page.java 新增Page这个类专门为分页提供必要信息 属性: `int start; `开始位置 `int count;` 每页显示的数量 `int total; `总共有多少条数据 `String param;` 参数(这个属性在后续有用到,但是分类的分页查询里并没有用到,请忽略) 方法: `getTotalPage` 根据 每页显示的数量count以及总共有多少条数据total,计算出总共有多少页 `getLast `计算出最后一页的数值是多少 `isHasPreviouse` 判断是否有前一页 `isHasNext` 判断是否有后一页 ``` package com.dodoke.util; public class Page { private int start; private int count; private int total; private String param; public int getStart() { return start; } public void setStart(int start) { this.start = start; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public Page(int start, int count) { super(); this.start = start; this.count = count; } public int getTotal() { return total; } public void setTotal(int total) { this.total = total; } public String getParam() { return param; } public void setParam(String param) { this.param = param; } public boolean isHasPreviouse() { if (start == 0) return false; return true; } public boolean isHasNext() { if (start == getLast()) return false; return true; } public int getTotalPage() { int totalPage; // 假设总数是50,是能够被5整除的,那么就有10页 if (0 == total % count) totalPage = total / count; // 假设总数是51,不能够被5整除的,那么就有11页 else totalPage = total / count + 1; if (0 == totalPage) totalPage = 1; return totalPage; } public int getLast() { int last; // 假设总数是50,是能够被5整除的,那么最后一页的开始就是45 if (0 == total % count) last = total - count; // 假设总数是51,不能够被5整除的,那么最后一页的开始就是50 else last = total - total % count; last = last < 0 ? 0 : last; return last; } } ``` # 步骤 3 : 获取分页参数 获取分页信息是在BaseBackServlet的service方法中 ``` int start = 0; int count = 5; String startTmp = request.getParameter("page.start"); String countTmp = request.getParameter("page.count"); if (null != startTmp) { start = Integer.parseInt(startTmp); } if (null != countTmp) { count = Integer.parseInt(countTmp); } Page page = new Page(start, count); ``` 获取网页上传递来的开始位置,以及每页需要显示的数量 如果传递数据过来,开始位置取0,每页显示的数量取默认值:5. ``` package com.dodoke.controller; import java.lang.reflect.Method; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.dodoke.dao.impl.CategoryDaoImpl; import com.dodoke.dao.inter.CategoryDao; import com.dodoke.util.Page; /** * Servlet implementation class BaseBackServlet */ @WebServlet("/BaseBackServlet") public abstract class BaseBackServlet extends HttpServlet { private static final long serialVersionUID = 1L; public abstract String add(HttpServletRequest request, HttpServletResponse response); public abstract String delete(HttpServletRequest request, HttpServletResponse response); public abstract String edit(HttpServletRequest request, HttpServletResponse response); public abstract String update(HttpServletRequest request, HttpServletResponse response); public abstract String list(HttpServletRequest request, HttpServletResponse response, Page page); public CategoryDao categoryDao = new CategoryDaoImpl(); public void service(HttpServletRequest request, HttpServletResponse response) { int start = 0; int count = 5; String startTmp = request.getParameter("page.start"); String countTmp = request.getParameter("page.count"); if (null != startTmp) { start = Integer.parseInt(startTmp); } if (null != countTmp) { count = Integer.parseInt(countTmp); } Page page = new Page(start, count); try { /* 借助反射,调用对应的方法 */ String method = (String) request.getAttribute("method"); Method m; String redirect; if ("list".equals(method)) { m = this.getClass().getMethod(method, javax.servlet.http.HttpServletRequest.class, javax.servlet.http.HttpServletResponse.class,Page.class); redirect = m.invoke(this, request, response, page).toString(); } else { m = this.getClass().getMethod(method, javax.servlet.http.HttpServletRequest.class, javax.servlet.http.HttpServletResponse.class); redirect = m.invoke(this, request, response).toString(); } /* 根据方法的返回值,进行相应的客户端跳转,服务端跳转,或者仅仅是输出字符串 */ System.out.println(redirect); if (redirect.startsWith("@")) { response.sendRedirect(redirect.substring(1)); } else if (redirect.startsWith("%")) { response.getWriter().print(redirect.substring(1)); } else { request.getRequestDispatcher(redirect).forward(request, response); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } } ``` # 步骤 4 : 基于分页参数,获取数据 接着就通过反射,访问了CategoryServlet的list()方法,并在其中通过categoryDAO,基于page的start,和count值,获取分页数据。 ``` List<Category> cs = categoryDao.list(page.getStart(),page.getCount()); ``` # 步骤 5 : 为page对象设置总数 除此之外,还为page对象添加了总数 ``` int total = categoryDao.getTotal(); page.setTotal(total); ``` 为什么要加这个总数? 因为在分页显示的时候,要依据这个总数来判断一共有多少页面,最后一页是多少。 接着通过 ``` request.setAttribute("page", page); ``` 把page对象,传参到了listCategory.jsp页面 # 步骤 6 : 为了便于理解,先来一个简化了的adminPage.jsp 在listCategory.jsp页面包含了分页专用jsp:adminPage.jsp 在其中,依据page对象,进行分页超链元素的显示 完整版的adminPage.jsp 比较复杂,为了便于大家理解,我先把完整版的adminPage.jsp简化一下 首先,分页超链的效果,用的Bootstrap的分页效果来制作 首页超链: ``` <li> <a href="?page.start=0" aria-label="Previous" > <span aria-hidden="true">«</span> </a> </li> ``` 上一页超链: ``` <li > <a href="?page.start=${page.start-page.count}" aria-label="Previous" > <span aria-hidden="true">‹</span> </a> </li> ``` 下一页超链: ``` <li > <a href="?page.start=${page.start+page.count}" aria-label="Next"> <span aria-hidden="true">›</span> </a> </li> ``` 最后一页 ``` <li > <a href="?page.start=${page.last}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> ``` 中间页 ``` <c:forEach begin="0" end="${page.totalPage-1}" varStatus="status"> <li> <a href="?page.start=${status.index*page.count}" class="current">${status.count}</a> </li> </c:forEach> ``` ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <script> $(function(){ $("ul.pagination li.disabled a").click(function(){ return false; }); }); </script> <nav> <ul class="pagination"> <li> <a href="?page.start=0" aria-label="Previous" > <span aria-hidden="true">«</span> </a> </li> <li > <a href="?page.start=${page.start-page.count}" aria-label="Previous" > <span aria-hidden="true">‹</span> </a> </li> <c:forEach begin="0" end="${page.totalPage-1}" varStatus="status"> <li> <a href="?page.start=${status.index*page.count}" class="current">${status.count}</a> </li> </c:forEach> <li > <a href="?page.start=${page.start+page.count}" aria-label="Next"> <span aria-hidden="true">›</span> </a> </li> <li > <a href="?page.start=${page.last}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> ``` # 步骤 7 : 完整版的adminPage.jsp 简化的adminPage.jsp 用于帮助大家理解,其存在的问题是,即便是没有下一页的数据了,下一页超链也可以点击,点出来的页面是空白的。(首页,上一页,下一页和最后一页都存在这个问题) 那么所谓的完整版的adminPage.jsp,就是对这些边界进行了处理。当没有下一页的时候,对应超链处于不可点击状态。 比如首页: 当page.hasPreviouse为false的时候,为首页连接套用Bootstrap样式 disabled ``` <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>> <a href="?page.start=0${page.param}" aria-label="Previous" > <span aria-hidden="true">&laquo;</span> </a> </li> ``` ![](https://box.kancloud.cn/756e933d2fcde8996e418619fed2453e_194x62.png) ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <script> $(function(){ $("ul.pagination li.disabled a").click(function(){ return false; }); }); </script> <nav> <ul class="pagination"> <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>> <a href="?page.start=0${page.param}" aria-label="Previous" > <span aria-hidden="true">«</span> </a> </li> <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>> <a href="?page.start=${page.start-page.count}${page.param}" aria-label="Previous" > <span aria-hidden="true">‹</span> </a> </li> <c:forEach begin="0" end="${page.totalPage-1}" varStatus="status"> <c:if test="${status.count*page.count-page.start<=20 && status.count*page.count-page.start>=-10}"> <li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>> <a href="?page.start=${status.index*page.count}${page.param}" <c:if test="${status.index*page.count==page.start}">class="current"</c:if> >${status.count}</a> </li> </c:if> </c:forEach> <li <c:if test="${!page.hasNext}">class="disabled"</c:if>> <a href="?page.start=${page.start+page.count}${page.param}" aria-label="Next"> <span aria-hidden="true">›</span> </a> </li> <li <c:if test="${!page.hasNext}">class="disabled"</c:if>> <a href="?page.start=${page.last}${page.param}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> ```