在Javaweb开发当中,分页技术是每个程序员都应该掌握的技术,近来学习了如何分页,其中有很多的细节要注意,对于自学者来说,搞清楚来龙去脉尤为重要,分清层次先后,会大大提高学习的效率,先将思路整理一下。
Java是一门面向对象的语言,分页用面向对象的思想去考虑,整个一个页面可以看做一个JavaBean,每次请求都是返回一个javaBean,那么这个页面有什么东西呢?第一个就是请求返回的内容(beanList),第二个是当前请求页码(pagecode),第三个是每页显示的记录数(pagesize),这个值可以进行设置,第四个是总的页数(totalpage),可用总的记录数(totalrecord)和pagesize计算出来,第五个比较隐蔽,就是请求路径(url),于是这个javaBen就出来了。
public class PageBean<T> {
private int pc;//当前页码
private int tr;//总记录数
private int ps;//每页记录数
private String url;//请求路径和参数,例如:/BookServlet?method=findXXX&cid=1&bname=2
private List<T> beanList;
// 计算总页数
public int getTp() {
int tp = tr / ps;
return tr % ps == 0 ? tp : tp + 1;
}
...省略getter和setter方法
接下来就需要把JavaBean所需数据填充进去,我们采用三层架构(servlet-service-dao)的思想去做。
从后台数据往前台做,dao可以从数据库得到beanlist,总的记录数pagerecord,service层无太多要做。接下来就是最重要的部分servlet层。
1,获取当前请求页码:request.getparamenter("pagecode")。
2,获取url:
/*
* http://localhost:8080/goods/BookServlet?methed=findByCategory&cid=xxx&pc=3
* /goods/BookServlet + methed=findByCategory&cid=xxx&pc=3
*/
private String getUrl(HttpServletRequest req) {
String url = req.getRequestURI() + "?" + req.getQueryString();
/*
* 如果url中存在pc参数,截取掉,如果不存在那就不用截取。
*/
int index = url.lastIndexOf("&pc=");
if(index != -1) {
url = url.substring(0, index);
}
return url;
}
最后就是页面pager.jsp代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript">
function _go() {
var pc = $("#pageCode").val();//获取文本框中的当前页码
if(!/^[1-9]\d*$/.test(pc)) {//对当前页码进行整数校验
alert('请输入正确的页码!');
return;
}
if(pc > ${pb.tp}) {//判断当前页码是否大于最大页
alert('请输入正确的页码!');
return;
}
location = "${pb.url}&pc=" + pc;
}
</script>
<div class="divBody">
<div class="divContent">
<%--上一页 --%>
<c:choose>
<c:when test="${pb.pc eq 1 }"><span class="spanBtnDisabled">上一页</span></c:when>
<c:otherwise><a href="${pb.url }&pc=${pb.pc-1}" class="aBtn bold">上一页</a></c:otherwise>
</c:choose>
<%--我们需要计算页码列表的开始和结束位置,即两个变量begin和end
计算它们需要通过当前页码!
1. 总页数不足6页--> begin=1, end=最大页
2. 通过公式设置begin和end,begin=当前页-1,end=当前页+3
3. 如果begin<1,那么让begin=1,end=6
4. 如果end>tp, 让begin=tp-5, end=tp
--%>
<c:choose>
<c:when test="${pb.tp <= 6 }">
<c:set var="begin" value="1"/>
<c:set var="end" value="${pb.tp }"/>
</c:when>
<c:otherwise>
<c:set var="begin" value="${pb.pc-2 }"/>
<c:set var="end" value="${pb.pc + 3}"/>
<c:if test="${begin < 1 }">
<c:set var="begin" value="1"/>
<c:set var="end" value="6"/>
</c:if>
<c:if test="${end > pb.tp }">
<c:set var="begin" value="${pb.tp-5 }"/>
<c:set var="end" value="${pb.tp }"/>
</c:if>
</c:otherwise>
</c:choose>
<c:forEach begin="${begin }" end="${end }" var="i">
<c:choose>
<c:when test="${i eq pb.pc }">
<span class="spanBtnSelect">${i }</span>
</c:when>
<c:otherwise>
<a href="${pb.url }&pc=${i}" class="aBtn">${i }</a>
</c:otherwise>
</c:choose>
</c:forEach>
<%-- 计算begin和end --%>
<%-- 如果总页数<=6,那么显示所有页码,即begin=1 end=${pb.tp} --%>
<%-- 设置begin=当前页码-2,end=当前页码+3 --%>
<%-- 如果begin<1,那么让begin=1 end=6 --%>
<%-- 如果end>最大页,那么begin=最大页-5 end=最大页 --%>
<%-- 显示点点点 --%>
<c:if test="${end < pb.tp }">
<span class="spanApostrophe">...</span>
</c:if>
<%--下一页 --%>
<c:choose>
<c:when test="${pb.pc eq pb.tp }"><span class="spanBtnDisabled">下一页</span></c:when>
<c:otherwise><a href="${pb.url }&pc=${pb.pc+1}" class="aBtn bold">下一页</a></c:otherwise>
</c:choose>
<%-- 共N页 到M页 --%>
<span>共${pb.tp }页</span>
<span>到</span>
<input type="text" class="inputPageCode" id="pageCode" value="${pb.pc }"/>
<span>页</span>
<a href="javascript:_go();" class="aSubmit">确定</a>
</div>
</div>
在需要分页的页面引入这个pager.jsp文件即可。
总结:整个过程就是一个pageBean的填充过程,各层能填进去的数据逐步填进去,完成了pageBean所需的全部数据,个人觉得在pager.jsp部分,begin和end值是用标签来做的,页码出现了大量跟业务逻辑有关的代码,如果把它放到pageBean里面来做,pager.jsp更加干净整洁,而pageBean也更加面向对象。
说明:以上源码部分来自视频