java 分页

时间:2025-03-04 20:51:31

在网上看了好多的struts2的分页,虽然都实现了分页的功能,但是感觉不是非常好,需要我们在每次写分页的时候做很多的工作,而我认为分页应该是一个通用的组件,开发人员在开发的过程中不应该在分页上花费太多的精力。所以,一直想封装一个比较通用的分页组件,而设计分页组件的时候,怎样保证动态查询的参数不丢失,成为实现的一个难点。         

该组件采用自定struts2标签的方式实现。         

首先建立一个构建分页标签信息的类:

/**
 * *构建分页标签体的类
 * *@authorJava软件工程师,艳子。
 * *@version1.0
 */
public class Pages extends Component {
	private HttpServletRequest request;
	private String pageNo; // 当前页码
	private String total; // 总页数
	private String styleClass; // 分页的样式
	private String theme; // 分页的主题
	private String url; // action的路径
	private String urlType; // 路径的类型,主要用于URL重写的扩展

	// 省略get、set方法
	public Pages(ValueStack arg0, HttpServletRequest request) {
		super(arg0);
		 = request;
	}

	@Override
	public boolean end(Writer writer, String body) {
		boolean result = (writer);
		try {
			// 从ValueStack中取出数值
			Object obj = ().findValue(pageNo);
			pageNo = ((Integer) obj);
			obj = ().findValue(total);
			total = ((Integer) obj);

			StringBuilder str = new StringBuilder();
			Map cont = ().getContext();
			StrutsRequestWrapper req = (StrutsRequestWrapper) cont
					.get(StrutsStatics.HTTP_REQUEST);
			if (url == null || "".equals(url)) {
				url = (String) req
						.getAttribute(".request_uri");
			}

			String pageNoStr = "?pageNo=";
			if ("dir".equals(urlType)) {
				// 当url的类型为目录类型时,比如http://localhost:8090/yongtree/page/1
				pageNoStr = "";
				if ("1".equals(pageNo)) {// 第一页时
					if (("/") != () - 1) {
						if (("1") == () - 1) {// 如果有页码1,则去掉1
							url = (0, () - 1);
						} else if (("/") != () - 1) {// 如果没有页码1,并且最后不是'/'时,加上'/'
							url = url + "/";
						}
					}
				} else {
					url = (0, ("/") + 1);
				}
			}
			// 下面这段处理主要是用来处理动态查询的参数,并拼接成url
			StringBuffer perUrl = new StringBuffer("");
			if (().size() != 0) {
				Iterator iter = ().keySet().iterator();
				while (()) {
					String key = (String) ();
					Object o = ().get(key);
					("&").append(key).append("=").append(o);
				}
			}
			Integer cpageInt = (pageNo);
			("<span ");
			if (styleClass != null) {
				(" class='" + styleClass + "'>");
			} else {
				(">");
			}
			// 文本样式
			if (theme == null || "text".equals(theme)) {
				// 当前页与总页数相等
				if ((total)) {
					// 如果total = 1,则无需分页,显示“[第1页] [共1页]”
					if ("1".equals(total)) {
						("[第 " + pageNo + " 页]");
						(" [共 " + total + " 页]");
					} else {
						// 到达最后一页,显示“[首页] [上一页] [末页]”
						("<a href='" + url + pageNoStr + "1" + perUrl
								+ "'>[首页]</a> ");
						("<a href='" + url + pageNoStr
								+ (cpageInt - 1) + perUrl + "'>[上一页]</a>");
						(" <a href='" + url + pageNoStr + total
								+ perUrl + "'>[末页]</a> ");
					}
				} else {
					// 当前页与总页数不相同
					if ("1".equals(pageNo)) {
						// 第一页,显示“[首页] [下一页] [末页]”
						("<a href='" + url + pageNoStr + "1" + perUrl
								+ "'>[首页]</a>");
						("<a href='" + url + pageNoStr
								+ (cpageInt + 1) + perUrl + "'>[下一页]</a>");
						("<a href='" + url + pageNoStr + total
								+ perUrl + "'>[末页]</a>");
					} else {
						// 不是第一页,显示“[首页] [上一页] [下一页] [末页]”
						("<a href='" + url + pageNoStr + "1" + perUrl
								+ "'>[首页]</a>");
						("<a href='" + url + pageNoStr
								+ (cpageInt - 1) + perUrl + "'>[上一页]</a>");
						("<a href='" + url + pageNoStr
								+ (cpageInt + 1) + perUrl + "'>[下一页]</a>");
						("<a href='" + url + pageNoStr + total
								+ perUrl + "'>[末页]</a>");
					}
				}
			} else if ("number".equals(theme)) {
				// 数字样式 [1 2 3 4 5 6 7 8 9 10 > >>]
				Integer totalInt = (total);
				// 如果只有一页,则无需分页

				("[ ");
				if (totalInt == 1) {
					("<strong>1</strong> ");
				} else {
					if (cpageInt > 1) {
						// 当前不是第一组,要显示“<< <”
						// <<:返回前一组第一页
						// <:返回前一页
						("<a href='" + url + pageNoStr + "1" + perUrl
								+ "'>?</a> ");
						("<a href='" + url + pageNoStr
								+ (cpageInt - 1) + perUrl);
						("'>‹</a> ");

					} else {

						("? ‹ ");
					}
					int v = (cpageInt - 4) > 0 ? (cpageInt - 4) : 1;
					int v1 = (cpageInt + 4) < totalInt ? (cpageInt + 4)
							: totalInt;
					if (v1 == totalInt) {
						v = totalInt - 10;
						v = (v <= 0 ? 1 : v); // 如果为负数,则修改为1
					} else if (v == 1 && v1 < totalInt) {
						v1 = totalInt > 10 ? 10 : totalInt;
					}
					// 10个为一组显示
					for (int i = v; i <= v1; i++) {
						if (cpageInt == i) { // 当前页要加粗显示
							("<strong>" + i + "</strong> ");
						} else {
							// ("<a href='"+url + i +perUrl+"'>" + i +
							// "</a> ");
							("<a href='" + url + pageNoStr + i
									+ perUrl + "'>" + i + "</a> ");
						}
					}
					// 如果多于1组并且不是最后一组,显示“> >>”
					if (cpageInt < totalInt) {
						// >>:返回下一组最后一页
						// >:返回下一页
						("<a href='" + url + pageNoStr
								+ (cpageInt + 1) + perUrl);
						("'>›</a> ");
						("<a href='" + url + pageNoStr + totalInt
								+ perUrl);
						("'>?</a> ");
					} else {
						("› ? ");
					}
				}
				("]");
			}
			("</span>");
			(());
		} catch (IOException ex) {
			();
		}
		return result;
	}
}

 

 

自定义分页标签结构的类:

/**
 * *自定义分页标签结构或属性
 * @author艳子, 
 * *@version1.0
 */
public class PageTag extends ComponentTagSupport {
	private String pageNo;
	private String total;
	private String styleClass;
	private String theme;
	private String url;
	private String urlType;

	public void setUrlType(String urlType) {
		 = urlType;
	}

	public void setUrl(String url) {
		 = url;
	}

	public void setTheme(String theme) {
		 = theme;
	}

	public void setStyleClass(String styleClass) {
		 = styleClass;
	}

	public void setPageNo(String pageNo) {
		 = pageNo;
	}

	public void setTotal(String total) {
		 = total;
	}

	@Override
	public Component getBean(ValueStack arg0, HttpServletRequest arg1,
			HttpServletResponse arg2) {
		return new Pages(arg0, arg1);
	}

	protected void populateParams() {
		();
		Pages pages = (Pages) component;
		(pageNo);
		(total);
		(styleClass);
		(theme);
		(url);
		(urlType);
	}
}


 

创建自定义标签的tld文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
	<tlib-version>1.0</tlib-version>
	<jsp-version>1.2</jsp-version>
	<short-name>yt</short-name>
	<uri>/yongtree-tags</uri>
	<display-name>"Java软件工程师,专注于java领域新技术的研究和系统设计。的自定义标签"</display-name>
	<tag>
		<name>pages</name>
		<tag-class></tag-class>
		<body-content>jsp</body-content>
		<description>分页标签</description>
		<attribute>
			<name>pageNo</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>total</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		
		<attribute>
			<name>styleClass</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>分页标签的样式,不配置此项将采用默认的样式</description>
		</attribute>
		<attribute>
			<name>theme</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>分页的主题,现支持number|text两种主题</description>
		</attribute>
		<attribute>
			<name>url</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>分页提交的路径,默认不用配置该项,自动获取系统访问路径。</description>
		</attribute>
		<attribute>
			<name>urlType</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>
				url的类型,现在支持两种url类型,第一种默认的url,这种情况不需要设置;第二种情况是目录型的url,比如/yongtree,此种情况请配置成dir。此种情况不支持动态查询,故标签体中不能加入参数            </description>
		</attribute>
	</tag>
</taglib>

 

这样一个分页标签就实现完了,下一步让我们看看该怎样使用吧。  

在页面中引入自定义的标签库: <%@ taglib prefix="yt" uri="/yongtree-tags"%>

开始配置分页标签信息:

<br>
	共
	<s:property value="total" />
	页第
	<s:property value="pageNo" />
	页
	<br>
		<br>
			<yt:pages pageNo="pageNo" total="total" styleClass="page"
				theme="number"> <!—分页的动态查询参数需要全部注册在这里à     
				<s:param name="test1" value="test1"></s:param>
				<s:param name="test2" value="test2"></s:param>
				<s:param name="test3" value="test3"></s:param>
			</yt:pages>  


这样一个分页组件就完成了,但是只是完成了表现上的功能,我们还需要在后台进行封装,我对它进行了封装,

做了一个

public class PageAction extends BaseAction {
	private Integer pageNo = 1;
	private Integer everyPage = 10;
	private Integer total;
	Page page = new Page();

	public Integer getPageNo() {
		return pageNo;
	}

	public void setPageNo(Integer pageNo) {
		(pageNo);
		 = pageNo;
	}

	public Integer getEveryPage() {
		return everyPage;
	}

	public void setEveryPage(Integer everyPage) {
		 = everyPage;
	}

	public Page getPage() {
		return page;
	}

	public void setPage(Page page) {
		 = page;
	}

	public Integer getTotal() {
		return ();
	}

	public void setTotal(Integer total) {
		 = total;
	}
}