java 分页

本文介绍了一种Struts2框架下的通用分页组件实现方法,通过自定义标签简化了分页操作并确保动态查询参数不丢失。该组件支持不同主题风格及URL重写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

/**
 * *构建分页标签体的类
 * *@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);
		this.request = request;
	}

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

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

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

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

					} else {

						str.append("? ‹ ");
					}
					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) { // 当前页要加粗显示
							str.append("<strong>" + i + "</strong> ");
						} else {
							// str.append("<a href='"+url + i +perUrl+"'>" + i +
							// "</a> ");
							str.append("<a href='" + url + pageNoStr + i
									+ perUrl + "'>" + i + "</a> ");
						}
					}
					// 如果多于1组并且不是最后一组,显示“> >>”
					if (cpageInt < totalInt) {
						// >>:返回下一组最后一页
						// >:返回下一页
						str.append("<a href='" + url + pageNoStr
								+ (cpageInt + 1) + perUrl);
						str.append("'>›</a> ");
						str.append("<a href='" + url + pageNoStr + totalInt
								+ perUrl);
						str.append("'>?</a> ");
					} else {
						str.append("› ? ");
					}
				}
				str.append("]");
			}
			str.append("</span>");
			writer.write(str.toString());
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return result;
	}
}

 

 

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

/**
 * *自定义分页标签结构或属性
 * @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) {
		this.urlType = urlType;
	}

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

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

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

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

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

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

	protected void populateParams() {
		super.populateParams();
		Pages pages = (Pages) component;
		pages.setPageNo(pageNo);
		pages.setTotal(total);
		pages.setStyleClass(styleClass);
		pages.setTheme(theme);
		pages.setUrl(url);
		pages.setUrlType(urlType);
	}
}


 

创建自定义标签的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>yt</short-name>
	<uri>/yongtree-tags</uri>
	<display-name>"Java软件工程师,专注于java领域新技术的研究和系统设计。的自定义标签"</display-name>
	<tag>
		<name>pages</name>
		<tag-class>com.baiyyy.polabs.tag.PageTag</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,比如http://blog.youkuaiyun.com/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>  


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

做了一个PageAction.java

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) {
		this.page.setCurrentPage(pageNo);
		this.pageNo = pageNo;
	}

	public Integer getEveryPage() {
		return everyPage;
	}

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

	public Page getPage() {
		return page;
	}

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

	public Integer getTotal() {
		return this.page.getTotalPage();
	}

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



 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值