Java标签之自定义分页标签

雨蝶 – 李翊君–:– / 03:50
(*+﹏+*)

做过Java Web项目的开发工程师都知道,如果单纯的使用jsp脚本开发,糅合内容和行为逻辑与一体是一个非常不好的体验,更不易于维护。所以采用了JSTL标签库,用于分离数据显示和业务逻辑,简易开发,带来优雅编程体验。JSTL 即:JSP Standard Tag Library,一个JSP标签集合,它封装了JSP应用的通用核心功能。他依赖于standard.jar和jstl.jar两个jar包。

JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。尽量只是用核心标签,包括<c:if>、<c:choose>、<c:when>、<c:otherwise>、<c:forEach>等,主要用于构造循环和分支结构以控制显示逻辑。标签引用:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

格式化标签一般用于日期相关的数据处理。函数标签一般用于字符串相关的数据处理。当然,这次要记录的是如何自定义标签,增强自己的数据处理需要。这里以自定义分页标签为例。

1、实现Tag接口或者继承缺省适配的Tag相关类。

开发中通常不直接实现这些接口而是继承TagSupport/BodyTagSupport/SimpleTagSupport类,重写doStartTag()、doEndTag()等方法,定义标签要完成的功能。

现在已自定义分页标签为例,继承BodyTagSupport类,重写doStartTag方法。定义了一些属性。

  1. PageData pageData; // 分页类
  2. String funcName; // js 回调函数名
  3. String formId; // 表单的ID名
  4. String formUrl; // 表单提交的URL

重写doStartTag方法:

  1. @Override
  2. public int doStartTag() throws JspException {
  3.     JspWriter out = this.pageContext.getOut();
  4.     try {
  5.         if (pageData == null) {
  6.             return Tag.SKIP_BODY;
  7.         }
  8.         out.println(getPageHtml());
  9.     } catch (IOException e) {
  10.         throw new JspException(e);
  11.     }
  12.     return Tag.EVAL_BODY_INCLUDE;
  13. }

在getPageHtml方法里根据逻辑拼接html分页列表,如一个简单的例子:

  1. private String getPageHtml() {
  2.         if (pageData == null) {
  3.             return “”;
  4.         }
  5.         StringBuilder sBuilder = new StringBuilder();
  6.         if (pageData.hasNext()) {
  7.             sBuilder.append(“<li><a href=\”javascript:void(0)\” onclick=\””).append(this.funcName)
  8.             .append(“(“).append(pageData.getPageNo()+1).append(“,”).append(pageData.getPageSize()).append(“,'”).append(formId).append(“‘,'”).append((formUrl == null || “”.equals(formUrl)?“”:formUrl))
  9.             .append(“‘);\”>下一页</a></li>”);
  10.         } else {
  11.             sBuilder.append(“<li class=\”disabled\”>下一页</li>”);
  12.         }
  13.         if (pageData.hasPrevious()) {
  14.             sBuilder.append(“<li><a href=\”javascript:void(0)\” onclick=\””).append(this.funcName)
  15.             .append(“(“).append(pageData.getPageNo()-1).append(“,”).append(pageData.getPageSize()).append(“,'”).append(formId).append(“‘,'”).append((formUrl == null || “”.equals(formUrl)?“”:formUrl))
  16.             .append(“‘);\”>上一页</a></li>”);
  17.         } else {
  18.             sBuilder.append(“<li class=\”disabled\”>上一页</li>”);
  19.         }
  20.         return sBuilder.toString();
  21.     }

2、编写扩展名为tld的标签描述文件对自定义标签进行定义。

pages.tld自定义标签描述了标签名,标签处理类、和相关属性定义描述:

  1. <tag>
  2.     <name>page</name>
  3.     <tag-class>com.common.test.PageTag</tag-class>
  4.     <description>分页标签–power by wenqy.com</description>
  5.     <attribute>
  6.       <name>pageData</name>
  7.       <required>true</required>
  8.       <rtexprvalue>true</rtexprvalue>
  9.       <description>封装分页数据类</description>
  10.     </attribute>
  11.     <attribute>
  12.       <name>funcName</name>
  13.       <required>false</required>
  14.       <rtexprvalue>true</rtexprvalue>
  15.       <description>选择页签触发的js函数名</description>
  16.     </attribute>
  17.     <attribute>
  18.       <name>formId</name>
  19.       <required>true</required>
  20.       <rtexprvalue>true</rtexprvalue>
  21.       <description>选择页签后要提交表单的ID</description>
  22.     </attribute>
  23.     <attribute>
  24.       <name>formUrl</name>
  25.       <required>false</required>
  26.       <rtexprvalue>true</rtexprvalue>
  27.       <description>选择页签后要跳转的页面URL</description>
  28.     </attribute>
  29.   </tag>

3、在JSP页面中使用taglib指令引用该标签库

Jsp头部引用tld标签描述文件。

<%@ taglib prefix="fns" uri="/WEB-INF/tlds/pages.tld" %>

调用自定义标签,formUrl属性非必须。

<fns:page pageData="${requestScope.pageData }" funcName="page" formId="myForm" />

4、js方法

表单里定义pageNo、pageSize两个隐藏域,并重写页签调用方法,使用jquery方法。

  1.  <script type=“text/javascript”>
  2.         // 参数: 页数、页大小、form ID、submit URL
  3.         function page(no, size,form,url) {
  4.             var re = /^[0-9]*$/;
  5.             if(!re.test(size)){
  6.                 alert(‘页大小为数字’);
  7.                 return;
  8.             }
  9.             if(!re.test(no)){
  10.                 alert(‘页数为数字’);
  11.                 return;
  12.             }
  13.             if (no) {
  14.                 $(“#pageNo”).val(no);
  15.             }
  16.             if (size) {
  17.                 $(“#pageSize”).val(size);
  18.             }
  19.             if (url) {
  20.                 $(“#” + form).attr(“action”,url);
  21.             }
  22.             $(“#” + form).submit();
  23.             return false;
  24.         }
  25. </script>

5、pageData分页类

  1. /**
  2.  * 
  3.  * @author wenqy
  4.  *
  5.  */
  6. public class PageData implements Serializable {
  7.     private static final long serialVersionUID = 8040968899344110256L;
  8.     protected static final int DEFAULT_PAGE_NO = 0;
  9.     protected static final int DEFAULT_PAGE_SISE = 0;
  10.     protected static final int DEFAULT_INDEX_BEGIN = 0;
  11.     protected static final int DEFAULT_INDEX_END = 0;
  12.     protected List<?> items; // 页数据
  13.     protected Object[][] results;
  14.     protected int pageNo; // 当前页
  15.     protected int pageSize; // 页大小
  16.     protected int pageCount; // 页数
  17.     protected int totalCount;
  18.     protected int handleCount;
  19.     protected int lastPageSize;
  20.     protected int columnCount;
  21.     protected int beginIndex;
  22.     protected int endIndex;
  23.     protected int[] indexes; // 记录每页的起始下标
  24.     protected String orderField; // 排序字段
  25.     protected boolean isOrderAsc; // 升降排序
  26.     protected String resInfo;
  27.     protected String pageCode;
  28.     public boolean hasNext() {
  29.         return (this.pageNo < this.pageCount);
  30.     }
  31.     public boolean hasPrevious() {
  32.         return (this.pageNo > 0);
  33.     }
  34.     public static int convertFromPageToStartIndex(int paramInt1, int paramInt2) {
  35.         return ((paramInt1 – 1) * paramInt2);
  36.     }
  37.     public int currentPageNo() {
  38.         return getPageNo();
  39.     }
  40.     public int getNextIndex() {
  41.         int i = getBeginIndex() + this.pageSize;
  42.         if (i >= this.totalCount)
  43.             return getBeginIndex();
  44.         return i;
  45.     }
  46.     public int getPreviousIndex() {
  47.         int i = getBeginIndex() – this.pageSize;
  48.         if (i < 0)
  49.             return 0;
  50.         return i;
  51.     }
  52.     public List<?> getItems() {
  53.         return this.items;
  54.     }
  55.     public void setItems(List<?> paramList) {
  56.         this.items = paramList;
  57.     }
  58.     public int getPageNo() {
  59.         return this.pageNo;
  60.     }
  61.     public void setPageNo(int paramInt) {
  62.         this.pageNo = paramInt;
  63.     }
  64.     public int getPageSize() {
  65.         return this.pageSize;
  66.     }
  67.     public void setPageSize(int paramInt) {
  68.         this.pageSize = paramInt;
  69.     }
  70.     public int getPageCount() {
  71.         if (this.totalCount < 0)
  72.             return –1;
  73.         if (this.totalCount == 0)
  74.             return 0;
  75.         if (this.pageSize > 0) {
  76.             int i = this.totalCount / this.pageSize;
  77.             if (this.totalCount % this.pageSize > 0)
  78.                 ;
  79.             this.pageCount = (++i);
  80.         } else {
  81.             this.pageCount = 1;
  82.             this.pageSize = this.totalCount;
  83.         }
  84.         return this.pageCount;
  85.     }
  86.     public void setPageCount(int paramInt) {
  87.         this.pageCount = paramInt;
  88.     }
  89.     public int getTotalCount() {
  90.         return this.totalCount;
  91.     }
  92.     public void setTotalCount(int paramInt) {
  93.         if (paramInt > 0) {
  94.             this.totalCount = paramInt;
  95.             if (this.pageSize <= 0)
  96.                 return;
  97.             int i = this.totalCount / this.pageSize;
  98.             if (paramInt % this.pageSize > 0)
  99.                 ;
  100.             this.indexes = new int[++i];
  101.             for (int j = 0; j < i; ++j)
  102.                 this.indexes[j] = (this.pageSize * j);
  103.         } else {
  104.             this.totalCount = 0;
  105.         }
  106.     }
  107.     public int getBeginIndex() {
  108.         return this.beginIndex;
  109.     }
  110.     public void setBeginIndex(int paramInt) {
  111.         if (this.totalCount <= 0)
  112.             this.beginIndex = 0;
  113.         else if (paramInt >= this.totalCount)
  114.             this.beginIndex = this.indexes[(this.indexes.length – 1)];
  115.         else if (paramInt < 0)
  116.             this.beginIndex = 0;
  117.         else if (this.pageSize > 0)
  118.             this.beginIndex = this.indexes[(paramInt / this.pageSize)];
  119.         else
  120.             this.beginIndex = paramInt;
  121.     }
  122.     public int getEndIndex() {
  123.         return this.endIndex;
  124.     }
  125.     public void setEndIndex(int paramInt) {
  126.         this.endIndex = paramInt;
  127.     }
  128.     public int getLastPageSize() {
  129.         if (this.totalCount < 0)
  130.             return –1;
  131.         if (this.totalCount == 0)
  132.             return 0;
  133.         int i = this.totalCount % this.pageSize;
  134.         if (i > 0)
  135.             return i;
  136.         return this.pageSize;
  137.     }
  138.     public void setLastPageSize(int paramInt) {
  139.         this.lastPageSize = paramInt;
  140.     }
  141.     public int getColumnCount() {
  142.         return this.columnCount;
  143.     }
  144.     public void setColumnCount(int paramInt) {
  145.         this.columnCount = paramInt;
  146.     }
  147.     public int getHandleCount() {
  148.         return this.handleCount;
  149.     }
  150.     public void setHandleCount(int paramInt) {
  151.         this.handleCount = paramInt;
  152.     }
  153.     public int[] getIndexes() {
  154.         return this.indexes;
  155.     }
  156.     public void setIndexes(int[] paramArrayOfInt) {
  157.         this.indexes = paramArrayOfInt;
  158.     }
  159.     public String getOrderField() {
  160.         return this.orderField;
  161.     }
  162.     public void setOrderField(String paramString) {
  163.         this.orderField = paramString;
  164.     }
  165.     public boolean isOrderAsc() {
  166.         return this.isOrderAsc;
  167.     }
  168.     public void setOrderAsc(boolean paramBoolean) {
  169.         this.isOrderAsc = paramBoolean;
  170.     }
  171.     public Object[][] getResults() {
  172.         return this.results;
  173.     }
  174.     public void setResults(Object[][] paramArrayOfObject) {
  175.         this.results = paramArrayOfObject;
  176.     }
  177.     public String getResInfo() {
  178.         return this.resInfo;
  179.     }
  180.     public void setResInfo(String paramString) {
  181.         this.resInfo = paramString;
  182.     }
  183. }

封装Dao层的分页方法,传入pageData。Jsp会被Java容器,如:Tomcat翻译成Servlet,获取pageContext对象,调用doStartTag方法。

pageData

使用标签库可以对内容显示和业务逻辑的解耦有很大帮助,如果觉得现有标签库不能满足需要还可以自定义标签。当然也是可以选择其他模板引擎,如freemarker、velocity等等。

参考:

http://tomcat.apache.org/taglibs/standard/ Standard Taglib

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

1 + 7 = ?