最近在学习Struts2,并使用Struts2开发系统。在网上看了好多的struts2的分页,虽然都实现了分页的功能,但是感觉不是非常好,需要我们在每次写分页的时候做很多的工作,而我认为分页应该是一个通用的组件,开发人员在开发的过程中不应该在分页上花费太多的精力。所以,一直想封装一个比较通用的分页组件,而设计分页组件的时候,怎样保证动态查询的参数不丢失,成为实现的一个难点。感谢tangshuo和shim的分享,让我实现了这样的一个分页组件。 该组件采用自定struts2标签的方式实现。 首先建立一个构建分页标签信息的类:Pages.java /** *构建分页标签体的类 *@authorJava软件工程师,专注于java领域新技术的研究和系统设计。 *@date2008-11-4下午02:52:19 *@version1.0 */ publicclass 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 publicboolean 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); }elseif(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>"); } } } elseif ("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 }elseif(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 /** *自定义分页标签结构或属性 *@authorJava软件工程师,专注于java领域新技术的研究和系统设计。 *@date2008-11-4下午03:00:40 *@version1.0 */ publicclass PageTag extends ComponentTagSupport { private String pageNo; private String total; private String styleClass; private String theme; private String url; private String urlType; publicvoid setUrlType(String urlType) { this.urlType = urlType; } publicvoid setUrl(String url) { this.url = url; } publicvoid setTheme(String theme) { this.theme = theme; } publicvoid setStyleClass(String styleClass) { this.styleClass = styleClass; } publicvoid setPageNo(String pageNo) { this.pageNo = pageNo; } publicvoid setTotal(String total) { this.total = total; } @Override public Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) { returnnew Pages(arg0, arg1); } protectedvoid 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./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.csdn.net/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 publicclass PageAction extends BaseAction { private Integer pageNo=1; private Integer everyPage=10; private Integer total; Page page=new Page(); public Integer getPageNo() { returnpageNo; } publicvoid setPageNo(Integer pageNo) { this.page.setCurrentPage(pageNo); this.pageNo = pageNo; } public Integer getEveryPage() { returneveryPage; } publicvoid setEveryPage(Integer everyPage) { this.everyPage = everyPage; } public Page getPage() { returnpage; } publicvoid setPage(Page page) { this.page = page; } public Integer getTotal() { returnthis.page.getTotalPage(); } publicvoid setTotal(Integer total) { this.total = total; } } 具体的相关实现可以参考 http://www./topic/14657 |
|