STRUTS2自定义分页标签及过程中的问题
2012-12-25 00:25
387 查看
分页标签的开发
一直想写一个自己用的顺手的分页标签。网上的标签大部分都是在标签内部自成体系,不方便和页面上的查询条件结合在一起,即使有这样的标签,也不一定符合自己的实际需要。在这种需求的驱使下,决定写一个自己的分页标签,能够方便的和页面查询结合在一起,也能满足项目中的大部分需要。在参考网上其他人的自定义分页标签的基础上,加上自己的一些个性化需求,完成了自定义分页标签的编写。分页标签的样式如下:
分页标签分为四部分:第一部分是记录数和总页数;第二部分是分页页码;第三部分是修改设置每页显示的记录数;第四部分是直接输入页码跳转。
STRUTS2下的自定义标签开发细节就不再复述,简单描述一下开发过程:
第一步:建立一个WEB工程
第二部:java部分的代码和普通WEB开发一样,路径在src目录的具体包中;
第三部:tld文件放置在/WEB-INF/下。
通过上述步骤的完成后,就可以直接利用建立的工程进行测试标签是否正确。多的不说了,直接把代码贴出来:
PagerTag.java
/** * TODO * Struts2Pager.java * Administrator2012-12-18 */ package com.citybug.tag; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.components.Component; import org.apache.struts2.views.jsp.ComponentTagSupport; import com.opensymphony.xwork2.util.ValueStack; /** * @author Administrator * */ public class PagerTag extends ComponentTagSupport { /** * */ private static final long serialVersionUID = 1L; private String pageSize; private String pageNo; private String recordCount; private String pageCount; private String recordNum; private String showChangePageSize; private String showJumpPage; private String formId; public String getPageSize(){ return pageSize; } public void setPageSize(String pageSize){ this.pageSize=pageSize; } public String getPageNo(){ return pageNo; } public void setPageNo(String pageNo){ this.pageNo=pageNo; } public String getRecordCount(){ return recordCount; } public void setRecordCount(String recordCount){ this.recordCount=recordCount; } public String getPageCount(){ return pageCount; } public void setPageCount(String pageCount){ this.pageCount=pageCount; } public String getShowChangePageSize(){ return showChangePageSize; } public void setShowChangePageSize(String showChangePageSize){ this.showChangePageSize=showChangePageSize; } public String getShowJumpPage(){ return showJumpPage; } public void setShowJumpPage(String showJumpPage){ this.showJumpPage=showJumpPage; } public String getFormId(){ return formId; } public void setFormId(String formId){ this.formId=formId; } public String getRecordNum(){ return recordNum; } public void setRecordNum(String recordNum){ this.recordNum=recordNum; } @Override public Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) { return new Pager(arg0,arg1); } protected void populateParams(){ super.populateParams(); Pager pager=(Pager)component; pager.setPageNo(pageNo); pager.setPageSize(pageSize); pager.setRecordCount(recordCount); pager.setPageCount(pageCount); pager.setShowChangePageSize(showChangePageSize); pager.setShowJumpPage(showJumpPage); pager.setFormId(formId); pager.setRecordNum(recordNum); } }
Pager.java
/** * TODO * Pager.java * Administrator2012-12-18 */ package com.citybug.tag; import java.io.IOException; import java.io.Writer; import java.util.Enumeration; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.StrutsStatics; import org.apache.struts2.components.Component; import org.apache.struts2.dispatcher.StrutsRequestWrapper; import com.opensymphony.xwork2.util.ValueStack; /** * @author Administrator * */ public class Pager extends Component { private HttpServletRequest request; private String pageNo; //当前页码 private String pageSize; //每页记录数 private String recordCount; //总记录数 private String pageCount; //总页数 private String showChangePageSize; private String showJumpPage; private String formId; private String recordNum; public HttpServletRequest getRequest() { return request; } public void setRequest(HttpServletRequest request) { this.request = request; } public String getPageNo(){ return pageNo; } public void setPageNo(String pageNo){ this.pageNo=pageNo; } public String getPageSize(){ return pageSize; } public void setPageSize(String pageSize){ this.pageSize=pageSize; } public String getRecordCount(){ return recordCount; } public void setRecordCount(String recordCount){ this.recordCount=recordCount; } public String setPageCount(){ return pageCount; } public void setPageCount(String pageCount){ this.pageCount=pageCount; } public Pager(ValueStack arg0, HttpServletRequest request) { super(arg0); this.request = request; } public String getShowChangePageSize(){ return showChangePageSize; } public void setShowChangePageSize(String showChangePageSize){ this.showChangePageSize=showChangePageSize; } public String getShowJumpPage(){ return showJumpPage; } public void setShowJumpPage(String showJumpPage){ this.showJumpPage=showJumpPage; } public String getFormId(){ return formId; } public void setFormId(String formId){ this.formId=formId; } public String getRecordNum(){ return recordNum; } public void setRecordNum(String recordNum){ this.recordNum=recordNum; } @Override public boolean end(Writer writer,String body) { boolean result = super.start(writer); int iPageNo; int iRecordCount; int iPageCount; int iPageSize; boolean bShowChangePageSize; boolean bShowJumpPage; StringBuilder sb = new StringBuilder(); try { //从ValueStack中取出数值 Object obj=this.getStack().findValue(pageNo); pageNo = String.valueOf((Integer)obj); obj=this.getStack().findValue(recordCount); recordCount = String.valueOf((Integer)obj); obj=this.getStack().findValue(pageSize); pageSize=String.valueOf((Integer)obj); obj=this.getStack().findValue(showChangePageSize); bShowChangePageSize=Boolean.valueOf(String.valueOf(obj)); obj=this.getStack().findValue(recordNum); recordNum=String.valueOf((Integer)obj); obj=this.getStack().findValue(showJumpPage); bShowJumpPage=Boolean.valueOf(String.valueOf(obj)); iPageSize=Integer.valueOf(pageSize); iPageNo=Integer.valueOf(pageNo); iRecordCount=Integer.valueOf(recordCount); iPageCount=(iRecordCount+iPageSize-1)/iPageSize; sb.append("<style type=\"text/css\">"); sb.append(".pagination {padding: 5px;float:right;font-size:10px;}"); sb.append(".pagination a, .pagination a:link, .pagination a:visited {padding:2px 5px;margin:2px;border:1px solid #aaaadd;text-decoration:none;color:#006699;}"); sb.append(".pagination a:hover, .pagination a:active {border: 1px solid #ff0000;color: #000;text-decoration: none;}"); sb.append(".pagination span.current {padding: 2px 5px;margin: 2px;border: 1px solid #ff0000;font-weight: bold;background-color: #ff0000;color: #FFF;}"); sb.append(".pagination span.disabled {padding: 2px 5px;margin: 2px;border: 1px solid #eee; color: #ddd;}"); sb.append("</style>\r\n"); sb.append("<div class=\"pagination\">\r\n"); if(iRecordCount == 0){ sb.append("<strong>没有可显示的项目</strong>\r\n"); }else{ //页号越界处理 if(iPageNo > iPageCount){ iPageNo = iPageCount; } if(iPageNo < 1){ iPageNo = 1; } // 把当前页号设置成请求参数 sb.append("<input type=\"hidden\" name=\"").append("pageNo") .append("\" value=\"").append(pageNo).append("\"/>\r\n"); // 输出统计数据 sb.append("共 <strong>").append(recordCount) .append("</strong> 项") .append(", 共 <strong>") .append(iPageCount) .append("</strong> 页: \r\n"); //上一页处理 if (iPageNo == 1) { sb.append("<span class=\"disabled\">« 上一页") .append("</span>\r\n"); } else { sb.append("<a href=\"javascript:turnOverPage(") .append((iPageNo - 1)) .append(")\">« 上一页</a>\r\n"); } //如果前面页数过多,显示"..." int start = 1; if(iPageNo > 4){ start = iPageNo - 1; sb.append("<a href=\"javascript:turnOverPage(1)\">1</a>\r\n") .append("<a href=\"javascript:turnOverPage(2)\">2</a>\r\n") .append("…\r\n"); } //显示当前页附近的页 int end = iPageNo + 1; if(end > iPageCount){ end = iPageCount; } for(int i = start; i <= end; i++){ if(iPageNo == i){ //当前页号不需要超链接 sb.append("<span class=\"current\">") .append(i) .append("</span>\r\n"); }else{ sb.append("<a href=\"javascript:turnOverPage(") .append(i) .append(")\">") .append(i) .append("</a>\r\n"); } } //如果后面页数过多,显示"..." if(end < iPageCount - 2){ sb.append("…\r\n"); } if(end < iPageCount - 1){ sb.append("<a href=\"javascript:turnOverPage(") .append(iPageCount - 1) .append(")\">") .append(iPageCount - 1) .append("</a>\r\n"); } if(end < iPageCount){ sb.append("<a href=\"javascript:turnOverPage(") .append(iPageCount) .append(")\">") .append(iPageCount) .append("</a>\r\n"); } //下一页处理 if (iPageNo == iPageCount) { sb.append("<span class=\"disabled\">下一页 »") .append("</span>\r\n"); } else { sb.append("<a href=\"javascript:turnOverPage(") .append((iPageNo + 1)) .append(")\">下一页 »</a>\r\n"); } if(bShowChangePageSize){ //每页记录数 sb.append("每页记录数:<select id=\"recordNum\" name=\"recordNum\" onChange=\"turnOverPage(" + pageNo + ")\">"); if(recordNum.equals("20")){ sb.append("<option value=\"20\" selected>20</option>"); }else{ sb.append("<option value=\"20\">20</option>"); } if(recordNum.equals("50")){ sb.append("<option value=\"50\" selected>50</option>"); }else{ sb.append("<option value=\"50\">50</option>"); } if(recordNum.equals("100")){ sb.append("<option value=\"100\" selected>100</option>"); }else{ sb.append("<option value=\"100\">100</option>"); } if(recordNum.equals("150")){ sb.append("<option value=\"150\" selected>150</option>"); }else{ sb.append("<option value=\"150\">150</option>"); } if(recordNum.equals("200")){ sb.append("<option value=\"200\" selected>200</option>"); }else{ sb.append("<option value=\"200\">200</option>"); } sb.append("</select>"); } if(bShowJumpPage){ //跳转页 sb.append(" 跳转到<input id=\"pageNum\" type=\"text\" name=\"pageNum\" size=\"2\" length=\"5\" ") .append("onKeyPress=\"inputInt(event)\" ") .append(">") .append("<a href=\"javascript:jumpPage();") .append("\">跳转 »</a>\r\n"); } // 生成提交表单的JS sb.append("<script language=\"javascript\">\r\n") .append(" function turnOverPage(no){\r\n") .append(" if(no>").append(iPageCount).append("){") .append(" no=").append(iPageCount).append(";}\r\n") .append(" if(no<1){no=1;}\r\n") .append(" document.getElementById('" + formId + "').pageNo.value=no;\r\n") .append(" document.getElementById('" + formId + "').submit();\r\n") .append(" }\r\n") .append(" function inputInt(event){\r\n") .append(" var keyNum;\r\n") .append(" var keyCode;\r\n") .append(" if(window.event){\r\n") .append(" keyNum=event.keyCode;\r\n") .append(" }else if(event.which){\r\n") .append(" keyNum=event.which;\r\n") .append(" }\r\n") .append(" if(keyNum<46 || keyNum>57){\r\n") .append(" if(window.event){\r\n") .append(" event.returnValue=false;\r\n") .append(" }else{\r\n") .append(" event.preventDefault();\r\n") .append(" }\r\n") .append(" }\r\n") .append(" }\r\n") .append(" function jumpPage(){\r\n") .append(" var no=1;\r\n") .append(" if(document.getElementsById('pageNum').value==''){\r\n") .append(" alert('跳转页码必须填写!');\r\n") .append(" }else{\r\n") .append(" no=parseInt(document.getElementsById('pageNum').value);\r\n") .append(" }\r\n") .append(" turnOverPage(no);\r\n") .append(" }\r\n") .append("</script>\r\n"); } sb.append("</div>\r\n"); writer.write(sb.toString()); } catch (IOException ex) { ex.printStackTrace(); } return result; } }
Pager.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>cb</short-name> <uri>/citybug-tags</uri> <display-name>"自定义分页标签"</display-name> <tag> <name>pager</name> <tag-class>com.citybug.tag.PagerTag</tag-class> <body-content>jsp</body-content> <description>分页标签</description> <attribute> <name>pageNo</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>recordCount</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>pageSize</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>showChangePageSize</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>showJumpPage</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>formId</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
2.自定义标签的打包
自定义标签经过测试没有问题后,就要打包成JAR文件用到项目中去了,如何打包呢?方法比较简单:建立一个空目录
到部署服务器下,把组成标签的java的class类复制到建立的目录中,当然,要保持class类的路径和tld中的类路径一致
把部署服务器下的“META_INF”复制到建立的目录中
把tld文件复制到META_INF目录中
选中目录中的全部文件,使用winrar压缩软件,把选中的文件制作成压缩包。压缩格式选择为“ZIP”,如果是“RAR”格式,项目运行时,会出现“打不开文件”的错误信息。然后将要锁文件后缀改为JAR即可。
把新建的JAR文件复制到项目的LIB目录下,就可以使用了。
3. 页面上如何使用
页面上使用和struts2自己的标签没有什么区别:在页面的开头引用标签:
<%@ taglib prefix="cb" uri="/citybug-tags" %>
这个自定义标签由于要达到和查询条件融合在一起,所以需要把标签和查询条件放置在同一个form中。
<cb:pager pageNo="page.pageNo" pageSize="page.pageSize" formId="form1" recordCount="page.recordCount" showChangePageSize="true" showJumpPage="true"/>在上面的标签使用中,有page对象,这就是action中用于返回分页信息的对象。这个对象的代码非常简单,仅仅包含三个属性和这三个属性的getter和setter方法。代码如下:
Page.java
/** * TODO * Page.java * Administrator2012-12-20 */ package com.citybug.comm; /** * @author Administrator * */ public class Page { private int pageNo; private int pageSize; private int recordCount; public int getPageNo(){ return pageNo; } public void setPageNo(int pageNo){ this.pageNo=pageNo; } public int getPageSize(){ return pageSize; } public void setPageSize(int pageSize){ this.pageSize=pageSize; } public int getRecordCount(){ return recordCount; } public void setRecordCount(int recordCount){ this.recordCount=recordCount; } }
那么在action中,需要一个通用方法,把page中的各个参数之间的逻辑关系表述清楚,我的代码如下:
private Page setPagePro(int recordCount){ Page page=null; int pageCount; int iPageNum; try{ pageNo=this.getPageNo(); pageSize=this.getPageSize(); recordNum=this.getRecordNum(); pageNum=this.getPageNum(); if(pageSize==0){ pageSize=20; } if(pageNo==0){ pageNo=1; } if(recordNum!=0){ if(pageSize!=recordNum){ pageSize=recordNum; } } if(pageNum!=null && !pageNum.equals("")){ iPageNum=Integer.valueOf(pageNum); if(iPageNum>0){ if(pageNo!=iPageNum){ pageNo=iPageNum; } } } pageCount=(recordCount+pageSize-1)/pageSize; if(pageNo>pageCount){ pageNo=pageCount; } page=new Page(); page.setPageNo(pageNo); page.setPageSize(pageSize); page.setRecordCount(recordCount); }catch(Exception ex){ ex.printStackTrace(); } return page; }
为什么上面要这么写,是因为标签中可以改变每页的记录数和页码的跳转,每页记录数是以默认值为准,还是以页面上“每页记录数”下拉框中选择的数量为准?是以默认的页码为准还是以跳转中输入的页码为准?就是上面这个过程要解决的问题。其中的逻辑并不复杂。
那么接下来,只要把记录list和page对象返回给jsp页面,分页就成功了!
4。分页标签开发中的几个注意事项:
list如何传入标签?在我们开发自定义标签时,可能会碰到要把一个list对象传给标签,然后由标签进行处理后,给出一个结果。但是struts2中却是把所有的参数认为是String。那么就会出现在自定义标签的java中要获得list对象时,就不知道如何才能获得这个list。在参照struts2的core中源码情况下,有了下面的解决办法:
在继承自“ComponentTagSupport”的类中,把list的变量类型设置为Object。
private Object list;
在继承自“Component”的类中,在方法“end(Writer writer,String body)”中获取list的对象时,用下面的语句进行转换:
obj=this.getStack().findValue((String)list); ArrayList<?> beanList = (ArrayList<?>)obj;
这样,就可以获得list的队列内容。至于如何使用,可以使用反射,也可以对队列进行类型转换等等,这就要看具体的需要了。
在标签中,传入的是字符串或者具体的值,而不是变量时,如何获取到值?
看完上面的自定义标签,在end过程中,看到取值使用的是 Object obj=this.getStack().findValue(pageNo); 的方法。那么就会形成一种思维定势,认为获取标签传入的值都是采用这样的方式获取值。但是并不是如此,这是因为JSP页面上是这么写的 pageNo=”page.pageNo".那么,如果是直接写成 pageNo=“1”,就不用再使用findValue这个方法了,而是直接使用pageNo变量即可。这本不是个问题,只是在此给提个醒.
相关文章推荐
- JSP自定义分页标签,Struts2分页标签
- struts2自定义分页标签
- Struts2自定义标签4自定义分页标签
- JSP自定义分页标签TAG全过程
- 在Struts2中实现自定义分页标签全攻略(一)
- struts2自定义分页标签
- 在Struts2中实现自定义分页标签
- struts2自定义分页标签
- 分析自定义数据分页标签的案例,上传分析过程。
- Asp.net中DataGrid控件的自定义分页以及存储过程的问题
- JSP自定义分页标签TAG全过程
- Asp.net中DataGrid控件的自定义分页以及存储过程的问题
- Struts2中实现自定义分页标签
- struts2、hibernate 分页(自定义标签)
- 在Struts2中实现自定义分页标签全攻略(二)
- Struts2中实现自定义分页标签2
- Struts2自定义分页标签
- Struts2中实现自定义分页标签
- struts2自定义分页标签
- Struts2标签<s:checkboxlist>回显问题