STRUTS2自定义分页标签及过程中的问题

来源:互联网 发布:济南停车收费软件 编辑:程序博客网 时间:2024/05/24 06:20
  1. 分页标签的开发   

   一直想写一个自己用的顺手的分页标签。网上的标签大部分都是在标签内部自成体系,不方便和页面上的查询条件结合在一起,即使有这样的标签,也不一定符合自己的实际需要。在这种需求的驱使下,决定写一个自己的分页标签,能够方便的和页面查询结合在一起,也能满足项目中的大部分需要。

       在参考网上其他人的自定义分页标签的基础上,加上自己的一些个性化需求,完成了自定义分页标签的编写。分页标签的样式如下:

       分页标签分为四部分:第一部分是记录数和总页数;第二部分是分页页码;第三部分是修改设置每页显示的记录数;第四部分是直接输入页码跳转。

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;}@Overridepublic 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变量即可。这本不是个问题,只是在此给提个醒.



原创粉丝点击