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;