用自定义标签实现分页

我们先分析一下分页标签的需求:
如下图:

 附件: 您所在的用户组无法下载或查看附件
如果我们要写出分页标签,最少我们要有三个变量,

curPage//当前页 --也就是说现在用户正在浏览第几页.
total //总记录数 -- 我们从数据库得到的总记录数
PAGE_SIZE//页大小 --也就是说每页我们用来显示多少数据,这一般是常量,有时在Servlet指定,有时在properties文件里读取.
总页数=total/PAGE_SIZE+1

有了上面的数据,那么实现上面图片的需求应该就没有问题了.
首页 -- 把当前页设为1;
上一页--把当前页-1,如果当前页小于1则当前页还是为1;
下一面--把当前页+1,如果当前页大于总页数,当前页不变
末页--把当前页设为总页数

显示最近的9个页面-- 把(当前页-4)到(当前页+4)的页码显示出来.
指定跳转 -- 把当前页设为指定的页数.如果指定页数小于1,则为1,如果大于总页数,则为总页数

其实,我们分页标签的主要目的就是把我们的数据分成N页,并方便用户快速访问自己需要的页面,也就是说,告诉接受处理显示数据的Serlvet,他 要负责处理显示的那一页的数据(也就是我们上面提到的当前页).具体实现的语句很简单,在这里,假设处理数据的Servlet的名字叫做 PageSerlvet,那么我们通过Get方法显示传参访问PageSerlvet,语句为:PageSerlvet?curpage=当前页

上面我们讲了很多的业务处理方式,现在提下自定义标签.如果你根本不会写自定义标签的话,那么你先找点浅的例子,这个例子不适合学习自定义标签~

用标签来实现以上的需求,我们必须得到我们要得到的三个参数(curPage,total,PAGE_SZIE),当然,用过自定义标签的朋友都知 道,用标签属性来传是最好的!那么,我们确定了用属性来传参,就不要用到标签体,所有,处理分页标签问题,我们还是用TagSupport来解决分页标 签.

下面,是我们的标签处理类ageTag.java

public class PageTag extends TagSupport {
/**
  * 当前页
  */
private String curPage;
/**
  * 总页数
  */
private String totalPage;
/**
  * 页大小(一页显示的大小)
  */
private String pageSize;

public void setCurPage(String curPage) {
  this.curPage = curPage;
}

public void setPageSize(String pageSize) {
  this.pageSize = pageSize;

public void setTotalPage(String totalPage) {
  this.totalPage = totalPage;
}
@Override
public int doStartTag() throws JspException {
  JspWriter out = pageContext.getOut();
  // 得到分页后的页数,(总页数/页大小)+1
  if (pageSize == null || pageSize == "") {
  pageSize = "1";
  }
  int pageNumber = (Integer.parseInt(totalPage) / Integer
    .parseInt(pageSize));
  if (Integer.parseInt(curPage) > pageNumber) {
  curPage = String.valueOf(pageNumber);
  }
  if (Integer.parseInt(curPage) < 1) {
  curPage = "1";
  }
  // 显示给用户操作的页面开始端
  int start = Integer.parseInt(curPage) - 4;
  // 显示给用户操作的页面结束端
  int end = Integer.parseInt(curPage) + 4;
  // 特殊情况处理(开始端小于0)
  if ((Integer.parseInt(curPage) - 4) <= 0) {
  start = 1;
  }
  // 特殊情况处理(结束端大于总页数)
  if ((Integer.parseInt(curPage) + 4) > pageNumber) {
  end = pageNumber;
  }
  try {
  out
    .print("<form action='bbs/SubjectListServlet'><table align=center><tr height=10 align=justify ><td width=100>");
  out
    .print("<a href='bbs/SubjectListServlet?curpage=1'>[首页]</a>  <a href='bbs/SubjectListServlet?curpage="
      + (((Integer.parseInt(curPage) - 1) == 0) ? curPage
        : (Integer.parseInt(curPage) - 1))
      + "'>[上一页]</a></td><td width=180 align=center>");
  for (int i = start; i <= end; i++) {
    if(i != Integer.parseInt(curPage)){
    out.print("<a href='bbs/SubjectListServlet?curpage=" + i + "'>["
      + i + "]</a>  ");
    }else{
    out.print("<b>"+i+"</b>  ");
    }
   
  }
  out
    .print("</td><td width=100><a href='bbs/SubjectListServlet?curpage="
      + (((Integer.parseInt(curPage) + 1) > pageNumber) ? curPage
        : (Integer.parseInt(curPage) + 1))
      + "'>[下一页]</a>  <a href='bbs/SubjectListServlet?curpage="
      + pageNumber + "'>[末页]</a>");
  out
    .print("</td><td width=100><input name='curpage' style='width:22px;height:22px;' /><input type=submit value=go /></td></tr></table></form>");
  } catch (IOException e) {
  e.printStackTrace();
  }
  return super.doStartTag();
}
}

也许看上去比较复杂,但是大家是否还记得在Serlvet里面输出HTML代码的例子,我们学Servlet的时候都是这么过来的, 虽然现在不推荐在java类用再写HTML语法, 但是分页标签就是用的这种理念去实现的,有点像include.

上面的代码一共分三总色.紫色主要是初始代标签属性,因为我们在用标签时,他会自己调用setter方法给属性传值.红色为doStartTag()方法.主要是输出我们想要的格式.在红色中有一块蓝色的代码.那都是给属性在特殊情况下赋初值.

下面是tag的tld文件.记住.这个文件一定要放在WEB-INF/tlds目录下.tlds是默认不存在的,手动创建!
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>My Taglib For Holle Word!</description>
<tlib-version>1.0</tlib-version>
<short-name>page</short-name>
<uri></uri>
<tag>
  <name>outpage</name>
  <tag-class>com.tag.PageTag</tag-class>
  <body-content>JSP</body-content>
  <attribute>
  <name>curPage</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
  <type>java.lang.String</type>
  </attribute>
  <attribute>
  <name>totalPage</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
  <type>java.lang.String</type>
  </attribute>
  <attribute>
  <name>pageSize</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
  <type>java.lang.String</type>
  </attribute>
</tag>
</taglib>


一个attribute表示定义一个属性.
name -属性名
required-是否为空
rtexprvalue-是不能用EL语言或表达式(这个是个人理解,因为我如果不加这对标签,那我就用不了EL给属性赋值)
type-属性类型

然后你就在你要用的JSP页面上加上
<%@ taglib prefix="page" uri="/WEB-INF/tlds/pageTag.tld" %>

<page:outpage pageSize="${pageSize }" totalPage="${totalPage }" curPage="${curpage}"></page:outpage>

如果你在测试的时候你可以不用EL语言测试,直接给值就可以了.比如写成
<page:outpage pageSize="10" totalPage="270" curPage="9"></page:outpage>
这样.显示出来的效果为:
简单,简易使用 package auvtech; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; public class PageTag extends TagSupport { private String name="page"; private String action; private int measurement; public void setName(String name) { this.name = name; } public void setAction(String action) { this.action = action; } public void setMeasurement(int measurement) { this.measurement = measurement; } @Override public int doStartTag() throws JspException { try{ JspWriter out = pageContext.getOut(); Pageination page=(Pageination)pageContext.getSession().getAttribute(name); //在page中只有3个属性是已知的,1,一共多少记录,2,一页显示多少记录,3,以及返回的结果集 //1.重新给page分布内容 setPage(page); //2.输出html out.print(getHtml(page)); //3.输出js out.print(getJs(page)); }catch(IOException ioException){ throw new JspException(ioException.getMessage() ); } return(SKIP_BODY); } private void setPage(Pageination page){ if (page.getMaxNoteNum() != 0) { // 一共多少页 if (page.getOnePageMaxNum() != 0&&page.getMaxNoteNum() % page.getOnePageMaxNum() == 0) { page.setMaxPageNum(page.getMaxNoteNum() / page.getOnePageMaxNum()); } else if(page.getOnePageMaxNum()!= 0){ page.setMaxPageNum(page.getMaxNoteNum() / page.getOnePageMaxNum() + 1); } }else { page.setMaxPageNum(0); } //设置当前页记录数目 if(page.getResultList()!= null) page.setCurrentPageNoteNum(page.resultList.size()); else page.setCurrentPageNoteNum(0); } //生成html代码 private String getHtml(Pageination page){ StringBuffer sb = new StringBuffer(); //添加一个尺寸框 sb.append("量度米尺:"); sb.append("<input text='text' id='onePageMaxNum' name='onePageMaxNum' size='2' value='"+page.getOnePageMaxNum()+"'/>"); sb.append("[ 总发信息 ]: " + page.getMaxNoteNum() + "条 ,当前是:第" + page.getCurrentPage() + " 页 / 共 " + page.getMaxPageNum() + "页 本页 " + page.getCurrentPageNoteNum() + " 条"); //首页,上一页,下一页,尾页 if(page.getCurrentPage()>1) sb.append(" <a onclick='firstPage();' style='cursor:pointer'>首页</a>"); else sb.append("首页"); if(page.getCurrentPage()>1) sb.append(" <a onclick='previousPage();' style='cursor:pointer'>上一页</a>"); else sb.append("上一页"); if(page.getCurrentPage()<page.getMaxPageNum()) sb.append(" <a onclick='nextPage();' style='cursor:pointer'>下一页</a>"); else sb.append("下一页"); if(page.getCurrentPage()<page.getMaxPageNum()) sb.append(" <a onclick='lastPage();' style='cursor:pointer'>尾页</a>"); else sb.append("尾页"); //跳转 sb.append(" 跳转到:<select name='goToPage' onchange='javascript:goPage(this.value)'>"); for (int i = 1; i <= page.getMaxPageNum(); i++) { sb.append("<option value=").append(i); if ( i == page.getCurrentPage()){ sb.append(" selected"); } sb.append(">第").append(i).append("页</option>"); } sb.append("</select>"); return sb.toString(); } //生成js代码 private String getJs(Pageination page){ StringBuffer sb=new StringBuffer(); sb.append("<script language=javascript>"); //跳转事件 sb.append("function goPage(cpage){").append("window.location='").append(action); sb.append("?currentPageNum='+").append("cpage"); sb.append("+'&onePageMaxNum='+").append("getMaxNum()"); sb.append(";}"); //得到分页米尺数值 sb.append("function getMaxNum(){"); sb.append("var val=document.getElementById('onePageMaxNum').value;"); sb.append("if(val=='') return "+measurement+";"); sb.append(" return document.getElementById('onePageMaxNum').value"); sb.append(";}\n"); //首页 sb.append("function firstPage(){"); sb.append("var loca='"+action+"?currentPageNum="+1+"&onePageMaxNum='+getMaxNum();"); sb.append("window.location.href=loca;"); sb.append("}\n"); //上一页 sb.append("function previousPage(){"); sb.append("var loca='"+action+"?currentPageNum="+(page.getCurrentPage()-1)+"&onePageMaxNum='+getMaxNum();"); sb.append("window.location.href=loca;"); sb.append("}"); //下一页 sb.append("function nextPage(){"); sb.append("var loca='"+action+"?currentPageNum="+(page.getCurrentPage()+1)+"&onePageMaxNum='+getMaxNum();"); sb.append("window.location.href=loca;"); sb.append("}\n"); //尾页 sb.append("function lastPage(){"); sb.append("var loca='"+action+"?currentPageNum="+page.getMaxPageNum()+"&onePageMaxNum='+getMaxNum();"); sb.append("window.location.href=loca;"); sb.append("}\n"); sb.append("</script>"); return sb.toString(); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值