JSP自定义分页标签
也可用于struts2等框架或纯jsp页面中
背景:
最近在学习jsp,使用到了分页功能,从网上,查了半天,也没找到合适的。于是就自己写了这个分页标签。
此标签不会生成样式代码,只是生成一系列的<a>标签,方便了显示样式的自定义。本人是jsp初学者,只是分享一下经验,各位大神不要喷我。
<a href="postlist.do?pn=1">首页</a>
<a href="postlist.do?pn=1">1</a>
<a href="postlist.do?pn=2">2</a>
<a href="postlist.do?pn=3">3</a>
<a href="postlist.do?pn=4">4</a>
<a href="postlist.do?pn=5">5</a>
<a href="postlist.do?pn=6">6</a>
<a href="postlist.do?pn=7">7</a>
<a href="postlist.do?pn=8">8</a>
<a href="postlist.do?pn=9">9</a>
<span>10</span> <!--当前页-->
<a href="postlist.do?pn=11">...</a>
<a href="postlist.do?pn=14">尾页</a>
效果图
一、实现lhp2012.tld标签描述文件
其存放路径为:WEB-INF\tlds\lhp2012.tld
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version>
<short-name>lhp2012</short-name>
<tag>
<name>pagination</name>
<tag-class>com.lhp2012.util.Pagination</tag-class>
<body-content>empty</body-content>
<attribute>
<name>pageTotal</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>pageNow</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>pageUrl</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>withFirstLast</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
二、实现java类com.lhp2012.util.Pagination
package com.coolpeng.framework.mvc.jsptag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; public class TmsPagination extends TagSupport { /** * Author lhp2012 */ private static final int linkSize = 10; private int pageTotal; private int pageNow; private String pageUrl; private boolean withFirstLast;// 是否输出“首页”“尾页”标记 public void setWithFirstLast(boolean withFirstLast) { this.withFirstLast = withFirstLast; } public void setPageTotal(int pageTotal) { this.pageTotal = pageTotal; } public void setPageNow(int pageNow) { this.pageNow = pageNow; } public void setPageUrl(String pageUrl) { this.pageUrl = pageUrl; } private String generateOneLink(int i) { StringBuffer s = new StringBuffer(); if (i == this.pageNow) { s.append(" <span>"); s.append(i); s.append("</span> "); } else { s.append(" <a href=\""); s.append(pageUrl); s.append(i); s.append("\">"); s.append(i); s.append("</a> "); } return s.toString(); } private void generateLinks(int begin, int end) throws JspTagException { try { JspWriter out = pageContext.getOut(); for (int i = begin; i <= end; i++) { out.print(this.generateOneLink(i)); } } catch (IOException ex2) { throw new JspTagException("错误"); } } private void generateSpecialLink(int i, String text) { StringBuffer s = new StringBuffer(); s.append(" <a href=\""); s.append(pageUrl); s.append(i); s.append("\">"); s.append(text); s.append("</a> "); JspWriter out = pageContext.getOut(); try { out.print(s.toString()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private int pageNowGroup() {// 从1开始的 return ((this.pageNow - 1) / linkSize) + 1; } private int groupSize() {// 从1开始 return ((this.pageTotal - 1) / linkSize) + 1; } private boolean isNowFirstGroup() { return this.pageNowGroup() == 1; } private boolean isNowLastGroup() { return this.pageNowGroup() == this.groupSize(); } private int getGroupBeginNoByNow() { return linkSize * (pageNowGroup() - 1) + 1; } private int getGroupEndNoByNow() { if (this.isNowLastGroup()) return this.pageTotal; else return this.getGroupBeginNoByNow() + 9; } private void generateNextGroupLink(int begin) throws IOException { generateSpecialLink(begin, "..."); } private void generatePreGroupLink(int end) { this.generateSpecialLink(end, "..."); } private void generateAllLinks() { try { int begin = this.getGroupBeginNoByNow(); int end = this.getGroupEndNoByNow(); if (this.pageTotal <= linkSize) { this.generateLinks(1, this.pageTotal); } else { if (isNowFirstGroup()) { this.generateLinks(begin, end); this.generateNextGroupLink(end + 1); } else if (isNowLastGroup()) { this.generatePreGroupLink(begin - 1); this.generateLinks(begin, end); } else { this.generatePreGroupLink(begin - 1); this.generateLinks(begin, end); this.generateNextGroupLink(end + 1); } } } catch (Exception e) { e.printStackTrace(); } } private void generateAllLinksWithFirstLast() { this.generateSpecialLink(1, "首页"); this.generateAllLinks(); this.generateSpecialLink(this.pageTotal, "尾页"); } @Override public int doStartTag() throws JspException { return EVAL_BODY_INCLUDE; } @Override public int doEndTag() throws JspException { JspWriter out = pageContext.getOut(); try { out.print("<div class='cp-pagination'>"); if (this.withFirstLast){ this.generateAllLinksWithFirstLast(); } else { this.generateAllLinks(); } out.print("</div>"); } catch (IOException e) { e.printStackTrace(); } return EVAL_PAGE; } }
三、修改web.xml文件
在</web-app>之上添加如下内容
<jsp-config>
<taglib>
<taglib-uri>/tld/lhp2012</taglib-uri>
<taglib-location>/WEB-INF/tlds/lhp2012.tld</taglib-location>
</taglib>
</jsp-config>
四、使用分页标签
一、在jsp页面上部加入
<%@ taglib uri="/tld/lhp2012" prefix="lhp" %>
二、在需要加入分页页码的地方,这样使用标签
<lhp:pagination withFirstLast="true" pageTotal="${totalPage}" pageUrl="postlist.do?pn=" pageNow="${pn}" />
三、标签参数说明
withFirstLast:是否显示“首页”“尾页”
pageTotal:共计有多少页,是个数值
pageUrl:页面url前缀
pageNow:当前第几页
.cp-pagination{ height: 40px; font-size: 13px; } .cp-pagination span,.cp-pagination a{ color: #000; line-height: 30px; width: 30px; margin-right: 10px; display: block; float: left; border: 1px solid #DDDDDD; text-align: center; } .cp-pagination span{ background-color: #187dd7; color: #ffffff; } .cp-pagination a{ color: #187dd7; }
附:后台struts2 Action 示例代码
public class PostList extends ActionSupport{
private PostDAO postDAO;
private List<Post> postList;
private int totalPage;
private int pageSize;
private int pn;
private User loginUser;
public String execute() throws Exception {
if(pn<=0)pn=1;
this.pageSize=15;//每页显示10个帖子
this.totalPage=postDAO.getPageCount(pageSize);
this.postList=postDAO.postListPage(pn, pageSize);
this.loginUser=(User)this.session.getAttribute(Constants.USER_KEY);
return SUCCESS;
}
//省略getter、setter
}
特别提醒:此标签仅仅是根据几个参数生成html页面的一系列<a>标签,后台业务逻辑没有在这个标签中涉及。
就这样吧,也不知道其他像我这样的初学者能不能看懂。
2015年10月16日22:00:42更新,代码
package com.coolpeng.framework.mvc.jsptag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; public class TmsPagination extends TagSupport { /** * Author lhp2012 */ private static final int linkSize = 10; private int pageTotal; private int pageNow; private String pageUrl; private boolean withFirstLast;// 是否输出“首页”“尾页”标记 public TmsPagination(int pageTotal, int pageNow, String pageUrl, boolean withFirstLast) { this.pageTotal = pageTotal; this.pageNow = pageNow; this.pageUrl = pageUrl; this.withFirstLast = withFirstLast; } public TmsPagination() { } public void setWithFirstLast(boolean withFirstLast) { this.withFirstLast = withFirstLast; } public void setPageTotal(int pageTotal) { this.pageTotal = pageTotal; } public void setPageNow(int pageNow) { this.pageNow = pageNow; } public void setPageUrl(String pageUrl) { this.pageUrl = pageUrl; } private String generateOneLink(int i) { StringBuffer s = new StringBuffer(); if (i == this.pageNow) { s.append(" <span>"); s.append(i); s.append("</span> "); } else { s.append(" <a href=\""); s.append(pageUrl); s.append(i); s.append("\">"); s.append(i); s.append("</a> "); } return s.toString(); } private String generateLinks(int begin, int end) { StringBuffer sb = new StringBuffer(); for (int i = begin; i <= end; i++) { sb.append(this.generateOneLink(i)); } return sb.toString(); } private String generateSpecialLink(int i, String text) { StringBuffer s = new StringBuffer(); s.append(" <a href=\""); s.append(pageUrl); s.append(i); s.append("\">"); s.append(text); s.append("</a> "); return s.toString(); } private int pageNowGroup() {// 从1开始的 return ((this.pageNow - 1) / linkSize) + 1; } private int groupSize() {// 从1开始 return ((this.pageTotal - 1) / linkSize) + 1; } private boolean isNowFirstGroup() { return this.pageNowGroup() == 1; } private boolean isNowLastGroup() { return this.pageNowGroup() == this.groupSize(); } private int getGroupBeginNoByNow() { return linkSize * (pageNowGroup() - 1) + 1; } private int getGroupEndNoByNow() { if (this.isNowLastGroup()) return this.pageTotal; else return this.getGroupBeginNoByNow() + 9; } private String generateNextGroupLink(int begin) { return generateSpecialLink(begin, "..."); } private String generatePreGroupLink(int end) { return this.generateSpecialLink(end, "..."); } private String generateAllLinks() { StringBuffer sb = new StringBuffer(); int begin = this.getGroupBeginNoByNow(); int end = this.getGroupEndNoByNow(); if (this.pageTotal <= linkSize) { sb.append(this.generateLinks(1, this.pageTotal)); } else { if (isNowFirstGroup()) { sb.append(this.generateLinks(begin, end)); sb.append(this.generateNextGroupLink(end + 1)); } else if (isNowLastGroup()) { sb.append(this.generatePreGroupLink(begin - 1)); sb.append(this.generateLinks(begin, end)); } else { sb.append(this.generatePreGroupLink(begin - 1)); sb.append(this.generateLinks(begin, end)); sb.append(this.generateNextGroupLink(end + 1)); } } return sb.toString(); } public String toPaginationHtml() { StringBuffer sb = new StringBuffer(); sb.append("<div class='cp-pagination'>"); if (this.withFirstLast) { sb.append(this.generateSpecialLink(1, "首页")); sb.append(this.generateAllLinks()); sb.append(this.generateSpecialLink(this.pageTotal, "尾页")); } else { sb.append(this.generateAllLinks()); } sb.append("</div>"); return sb.toString(); } @Override public int doStartTag() throws JspException { return EVAL_BODY_INCLUDE; } @Override public int doEndTag() throws JspException { JspWriter out = pageContext.getOut(); try { String html = toPaginationHtml(); out.print(html); } catch (IOException e) { e.printStackTrace(); } return EVAL_PAGE; } }
package com.coolpeng.framework.mvc.jsptag; import com.coolpeng.framework.db.PageResult; /** * Created by Administrator on 2015/10/16. */ public class TmsPaginationConvert { /** * Author lhp2012 */ private static final int linkSize = 10; private int pageTotal; private int pageNow; private String pageUrl; private boolean withFirstLast = true;// 是否输出“首页”“尾页”标记 public TmsPaginationConvert(int pageTotal, int pageNow, String pageUrl, boolean withFirstLast) { this.pageTotal = pageTotal; this.pageNow = pageNow; this.pageUrl = pageUrl; this.withFirstLast = withFirstLast; } public TmsPaginationConvert() { } public void setWithFirstLast(boolean withFirstLast) { this.withFirstLast = withFirstLast; } public void setPageTotal(int pageTotal) { this.pageTotal = pageTotal; } public void setPageNow(int pageNow) { this.pageNow = pageNow; } public void setPageUrl(String pageUrl) { this.pageUrl = pageUrl; } private String generateOneLink(int i) { StringBuffer s = new StringBuffer(); if (i == this.pageNow) { s.append(" <span>"); s.append(i); s.append("</span> "); } else { s.append(" <a href=\""); s.append(pageUrl); s.append(i); s.append("\">"); s.append(i); s.append("</a> "); } return s.toString(); } private String generateLinks(int begin, int end) { StringBuffer sb = new StringBuffer(); for (int i = begin; i <= end; i++) { sb.append(this.generateOneLink(i)); } return sb.toString(); } private String generateSpecialLink(int i, String text) { StringBuffer s = new StringBuffer(); s.append(" <a href=\""); s.append(pageUrl); s.append(i); s.append("\">"); s.append(text); s.append("</a> "); return s.toString(); } private int pageNowGroup() {// 从1开始的 return ((this.pageNow - 1) / linkSize) + 1; } private int groupSize() {// 从1开始 return ((this.pageTotal - 1) / linkSize) + 1; } private boolean isNowFirstGroup() { return this.pageNowGroup() == 1; } private boolean isNowLastGroup() { return this.pageNowGroup() == this.groupSize(); } private int getGroupBeginNoByNow() { return linkSize * (pageNowGroup() - 1) + 1; } private int getGroupEndNoByNow() { if (this.isNowLastGroup()) return this.pageTotal; else return this.getGroupBeginNoByNow() + 9; } private String generateNextGroupLink(int begin) { return generateSpecialLink(begin, "..."); } private String generatePreGroupLink(int end) { return this.generateSpecialLink(end, "..."); } private String generateAllLinks() { StringBuffer sb = new StringBuffer(); int begin = this.getGroupBeginNoByNow(); int end = this.getGroupEndNoByNow(); if (this.pageTotal <= linkSize) { sb.append(this.generateLinks(1, this.pageTotal)); } else { if (isNowFirstGroup()) { sb.append(this.generateLinks(begin, end)); sb.append(this.generateNextGroupLink(end + 1)); } else if (isNowLastGroup()) { sb.append(this.generatePreGroupLink(begin - 1)); sb.append(this.generateLinks(begin, end)); } else { sb.append(this.generatePreGroupLink(begin - 1)); sb.append(this.generateLinks(begin, end)); sb.append(this.generateNextGroupLink(end + 1)); } } return sb.toString(); } public String toPaginationHtml() { StringBuffer sb = new StringBuffer(); sb.append("<div class='cp-pagination'>"); if (this.withFirstLast) { sb.append(this.generateSpecialLink(1, "首页")); sb.append(this.generateAllLinks()); sb.append(this.generateSpecialLink(this.pageTotal, "尾页")); } else { sb.append(this.generateAllLinks()); } sb.append("</div>"); return sb.toString(); } }
JavaScript 版本的分页
function isArray(obj) { return Object.prototype.toString.call(obj) === "[object Object]"; } function isFunction(obj) { return Object.prototype.toString.call(obj) === "[object Function]"; } /** * demo1: * { * pageNumber:1, * pageCount:10, * linkRender:function(p){ * return "<a>" * } * } * * * demo2: * { * pageNumber:1, * recordCount:10, * linkRender:"/blog/dsds?pn=" * } * @param config */ function toPagination(config) { var PRE_BUTTON = "pre"; var PRE_GROUP_BUTTON = "preGroup"; var NEXT_BUTTON = "next"; var NEXT_GROUP_BUTTON = "nextGroup"; var HOME_BUTTON = "home"; var linkSize = config.linkSize || 10; var pageNumber = config.pageNumber || 1;// 当前是第几页 var recordCount = config.recordCount || 0; var pageSize = config.pageSize || 20; var pageCount = config.pageCount || (function () { //总共有多少页 var pageCount = parseInt(config.recordCount / pageSize, 10); pageCount = (config.recordCount % pageSize === 0) ? pageCount : (pageCount + 1); return pageCount; })(); var buttons = config.buttons || [HOME_BUTTON, PRE_BUTTON, NEXT_BUTTON, PRE_GROUP_BUTTON, NEXT_GROUP_BUTTON]; var linkRender = function (number, text, isEnable) { if (isFunction(config.linkRender)) { return config.linkRender(number, text, isEnable); } var clazz = isEnable ? "" : "disabled"; return "<a class='" + clazz + "' href='" + config.linkRender + number + "'>" + text + "</a>"; }; function hasButton(btnName) { var buttons = buttons; if (!isArray(buttons)) { return false; } return (buttons.indexOf(btnName) >= 0); } function pageNowGroup() {// 从1开始的 return parseInt((pageNumber - 1) / linkSize) + 1; } function isNowFirstGroup() { return pageNowGroup() == 1; } function isNowLastGroup() { return pageNowGroup() == groupSize(); } function groupSize() {// 从1开始 return parseInt((pageCount - 1) / linkSize) + 1; } function getGroupBeginNoByNow() { return linkSize * (pageNowGroup() - 1) + 1; } function getGroupEndNoByNow() { if (isNowLastGroup()) { return pageCount; } else { return getGroupBeginNoByNow() + (linkSize - 1); } } function generateNextGroupLink(begin) { return linkRender(begin, "...", true); } function generatePreGroupLink(end) { return linkRender(end, "...", true); } function generateOneLink(i) { if (i == pageNumber) { return "<span>" + i + "</span>"; } else { return linkRender(i, i, true); } } function generateLinks(begin, end) { var links = []; for (var i = begin; i <= end; i++) { links.push(generateOneLink(i)); } return links.join(""); } function generateAllLinks() { var links = []; var begin = getGroupBeginNoByNow(); var end = getGroupEndNoByNow(); if (pageCount <= linkSize) { links.push(generateLinks(1, pageCount)); } else { if (isNowFirstGroup()) { links.push(generateLinks(begin, end)); links.push(generateNextGroupLink(end + 1)); } else if (isNowLastGroup()) { links.push(generatePreGroupLink(begin - 1)); links.push(generateLinks(begin, end)); } else { links.push(generatePreGroupLink(begin - 1)); links.push(generateLinks(begin, end)); links.push(generateNextGroupLink(end + 1)); } } return links.join(""); } function toPaginationHtml() { var htmlArray = []; htmlArray.push("<div class='cp-pagination'>"); if (hasButton(HOME_BUTTON)) { htmlArray.push(linkRender(1, "首页", true)); htmlArray.push(generateAllLinks()); htmlArray.push(linkRender(pageCount, "尾页", true)); } else { htmlArray.push(generateAllLinks()); } htmlArray.push("</div>"); return htmlArray.join(""); } return toPaginationHtml(); } //if(window){ // window.toPagination = toPagination; //} //if(exports){ // exports.toPagination = toPagination; //} exports.toPagination = toPagination;