java自定义分页标签

来源:互联网 发布:arkit 知乎 编辑:程序博客网 时间:2024/05/01 21:53

为什么需要自定义标签

在开发项目过程中,我们经常有这样的体会:同一个控件我们可能多处使用,同时我们需要在基础的样式上加上自己的样式和操作的js代码;遇到这种情况,如果每个地方都copy代码的话那么,后期如果要做修改,那么维护的工作量是巨大的。基于这种情况,我们可以考虑使用自定义标签,实现代码的复用,易维护。
JSP自定义标签,实质上就是以标记的形式封装了一个俱有独立功能的Java类。标记的使用减少了直接嵌入JSP页面的Java代码,方便了页面的布局,并且有利于代码的复用,提高了开发的效率。

原理介绍

  1. JSP服务器解析标记的过程:
    当一个用户访问一个JSP页面时,这个请求被发送到JSP服务器,JSP服务器会根据这个请求去调用相应的页面,如果这个页面中有自定义的标记, JSP服务就会根据页面指令<%@ taglib>去访问TLD得到处理程序的相关信息,接着调用该处理程序的构造器方法,启动标记符处理程序,并读取标记符的属性和相应值。
  2. TLD文件
    TLD(TLD:Tag Library Descriptor标记库描述符)文件,标准的XML格式的标记定义文件,被用来存放标记符的信息。
  3. Taglib 指令
    <%@ taglib uri=”URIToTagLibrary” prefix=”tagPrefix” %>
    <% @ taglib %>指令声明此JSP文件使用了自定义的标记,同时引用标记库,也指定了他们的标记的前缀。必须在使用自定义标记之前使用<% @ taglib %>指令。
    属性:
    uri=”URIToTagLibrary” :Uniform Resource Identifier (URI)根据标记的前缀对自定义的标记进行唯一的命名,URI可以是一个相对或绝对的路径。
    prefix=”tagPrefix”:在自定义标记之前的前缀。

举例代码

PageUtil.java代码

package com.util;import java.util.List;public class PageUtil<T> {    // 以下4个属性必须指定    private List<T> records; // 分页数据    private int totalRecord; // 总记录数    private int pageNo; // 当前页码,第几页    private int pageSize; // 每页显示的记录数,每页显示多少条数据    private int totalPage; // 总页数    private int startIndex; // 开始索引    private int endIndex; // 结束索引    private int indexCount = 10;// 显示的索引数目,如:10的话, 则显示1-10, 2-11    // public Pagination() {}    public PageUtil(List<T> records,int totalRecord,int pageNo, int pageSize) {        this.records = records;        this.totalRecord = totalRecord;        this.pageNo = pageNo;        this.pageSize = pageSize;        // 根据总记录数和每页显示数计算总页数(totalRecord+pageSize->totalPage)        totalPage = this.totalRecord / this.pageSize;        totalPage = (this.totalRecord % pageSize == 0) ? totalPage: (totalPage + 1);        // 计算显示索引数目        if (indexCount > totalPage) {            indexCount = totalPage;        }        // 根据索引数目,当前页,总页数计算开始索引和结束索引(indexCount+pageNo+totalPage->startIndex+endIndex)        startIndex = indexCount / 2;        startIndex = pageNo- (indexCount % 2 == 0 ? (startIndex - 1) : startIndex);        endIndex = pageNo + indexCount / 2;        // 1 <= startIndex < pageNo < endIndex <= totalPage        // startIndex = pageNo - indexCount/2        // endIndex = pageNo + indexCount/2        if (startIndex < 1) {            startIndex = 1;            if (totalPage >= indexCount) {                endIndex = indexCount;            } else {                endIndex = totalPage;            }        }        if (endIndex > totalPage) {            endIndex = totalPage;            if (endIndex > indexCount) {                startIndex = endIndex - indexCount + 1;            } else {                startIndex = 1;            }        }    }    /**     * 获取分页数据     *      * @return     */    public List<T> getRecords() {        return records;    }    /**     * 获取总记录数     *      * @return     */    public int getTotalRecord() {        return totalRecord;    }    /**     * 当前页数(第几页)     *      * @return     */    public int getPageNo() {        return pageNo;    }    /**     * 每页显示数据记录数     *      * @return     */    public int getPageSize() {        return pageSize;    }    /**     * 总页数     *      * @return     */    public int getTotalPage() {        return totalPage;    }    /**     * 起始索引     *      * @return     */    public int getStartIndex() {        return startIndex;    }    /**     * 结束索引     *      * @return     */    public int getEndIndex() {        return endIndex;    }    /****************************************************************/    /************************ get/set方法 ******************************/    /****************************************************************/    public int getIndexCount() {        return indexCount;    }    public void setIndexCount(int indexCount) {        this.indexCount = indexCount;    }    @Override    public String toString() {        return "PageUtil [records=" + records + ", totalRecord=" + totalRecord                + ", pageNo=" + pageNo + ", pageSize=" + pageSize                + ", totalPage=" + totalPage + ", startIndex=" + startIndex                + ", endIndex=" + endIndex + ", indexCount=" + indexCount + "]";    }}

PageTag.java

package com.util;import java.io.IOException;import javax.servlet.jsp.JspContext;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.tagext.SimpleTagSupport;public class PageTag extends SimpleTagSupport {    /**     * 分页数据(required)     */    private PageUtil pagination;    /**     * 请求路径     */    private String href;    /**     * 分页div     */    private String divId;    /**     * 分页样式     */    private String divClass;    @Override    public void doTag() throws JspException, IOException {        // 缓冲字符串对象        StringBuffer strBuf = new StringBuffer();        strBuf.append("<script type=\"text/javascript\">\n");        strBuf.append("function paga_toPage(pageNo) {");        strBuf.append("window.location.href=\"").append(href);        if (href.indexOf("?") == -1) {            strBuf.append("?");        } else {            strBuf.append("&");        }        strBuf.append("pageNo=\"").append("+pageNo;").append("}");        strBuf.append(" </script> ");        strBuf.append(" <div id=\"").append(divId).append("\" class=\"")                .append(divClass).append("\"> ");        // 上一页        if (pagination.getPageNo() == 1) {            strBuf.append(" <a>&#9668;</a>");        } else {            strBuf.append(" <a onclick=\"paga_toPage(")                    .append(pagination.getPageNo() - 1)                    .append(")\"> &#9668; </a> ");        }        // 容器        strBuf.append(" <span>");        if (pagination.getStartIndex() != 1) {            // 显示第一页索引            strBuf.append(" <a").append(" onclick=\"paga_toPage(").append(1)                    .append(");\">").append(1).append("</a> ");        }        // 显示省略号        if (pagination.getStartIndex() > 2) {            strBuf.append(" <i>...</i> ");        }        // 分页条主体        for (int i = pagination.getStartIndex(); i <= pagination.getEndIndex(); i++) {            if (pagination.getPageNo() == i) {                strBuf.append(" <a class=\"current\">").append(i)                        .append("</a> ");            } else {                strBuf.append(" <a onclick=\"paga_toPage(").append(i)                        .append(");\">").append(i).append("</a> ");            }        }        // 显示省略号        if (pagination.getEndIndex() < pagination.getTotalPage() - 1) {            strBuf.append(" <i>...</i> ");        }        if (pagination.getEndIndex() != pagination.getTotalPage()) {            // 显示最后一页索引            strBuf.append(" <a").append(" onclick=\"paga_toPage(")                    .append(pagination.getTotalPage()).append(");\">")                    .append(pagination.getTotalPage()).append("</a>");        }        // 容器结尾        strBuf.append(" </span> ");        // 下一页        if (pagination.getPageNo() == pagination.getTotalPage()) {            strBuf.append(" <a>&#9658;</a> ");            // strBuf.append("<a">末页</a> ");        } else {            strBuf.append(" <a onclick=\"paga_toPage(")                    .append(pagination.getPageNo() + 1)                    .append(")\"> &#9658; </a> ");            // strBuf.append(" <a onclick=\"paga_toPage(").append(pagination.getTotalPage()).append(")\">末页</a> ");        }        strBuf.append(" </div> ");        JspContext ctx = getJspContext();         // 获取页面输出流,并输出字符串        JspWriter out = ctx.getOut();        out.print(strBuf.toString());    }    public PageUtil getPagination() {        return pagination;    }    public void setPagination(PageUtil pagination) {        this.pagination = pagination;    }    public String getHref() {        return href;    }    public void setHref(String href) {        this.href = href;    }    public String getDivId() {        return divId;    }    public void setDivId(String divId) {        this.divId = divId;    }    public String getDivClass() {        return divClass;    }    public void setDivClass(String divClass) {        this.divClass = divClass;    }}

PageTag.tld

<?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"    version="2.0">    <description>自定义标签类</description>    <tlib-version>1.0</tlib-version>    <short-name>Mytaglib</short-name>    <uri>/MyPageTag</uri>    <tag>        <description>分页标签</description>        <name>Pagination</name>        <tag-class>com.util.PageTag</tag-class>        <body-content>empty</body-content>        <attribute>            <name>pagination</name>            <required>true</required>            <rtexprvalue>true</rtexprvalue>            <type>java.lang.Object</type>        </attribute>        <attribute>            <name>divId</name>            <required>false</required>        </attribute>        <attribute>            <name>divClass</name>            <required>false</required>        </attribute>        <attribute>            <name>href</name>            <required>false</required>            <rtexprvalue>true</rtexprvalue>        </attribute>    </tag></taglib>

page.css

@CHARSET "UTF-8";#pagination {    display: inline-block;    vertical-align: middle;    border-radius: 4px;    padding: 1px 2px 4px 2px;    border-top: 1px solid #AEAEAE;    border-bottom: 1px solid #FFFFFF;    background-color: #DADADA;    background-image: -webkit-linear-gradient(top, #DBDBDB, #E2E2E2);    background-image:    -moz-linear-gradient(top, #DBDBDB, #E2E2E2);    background-image:     -ms-linear-gradient(top, #DBDBDB, #E2E2E2);    background-image:      -o-linear-gradient(top, #DBDBDB, #E2E2E2);    background-image:         linear-gradient(top, #DBDBDB, #E2E2E2);}#pagination a, #pagination i {    display: inline-block;    vertical-align: middle;    width: 22px;    color: #7D7D7D;    text-align: center;    font-size: 10px;    padding: 3px 0 2px 0;    -webkit-user-select:none;       -moz-user-select:none;        -ms-user-select:none;         -o-user-select:none;            user-select:none;}#pagination a {    margin: 0 2px 0 2px;    border-radius: 4px;    border: 1px solid #E3E3E3;    cursor: pointer;    box-shadow: inset 0 1px 0 0 #FFF, 0 1px 2px #666;    text-shadow: 0 1px 1px #FFF;    background-color: #E6E6E6;    background-image: -webkit-linear-gradient(top, #F3F3F3, #D7D7D7);    background-image:    -moz-linear-gradient(top, #F3F3F3, #D7D7D7);    background-image:     -ms-linear-gradient(top, #F3F3F3, #D7D7D7);    background-image:      -o-linear-gradient(top, #F3F3F3, #D7D7D7);    background-image:         linear-gradient(top, #F3F3F3, #D7D7D7);}#pagination i {    margin: 0 3px 0 3px;}#pagination a.current {    border: 1px solid #E9E9E9;    box-shadow: 0 1px 1px #999;    background-color: #DFDFDF;    background-image: -webkit-linear-gradient(top, #D0D0D0, #EBEBEB);    background-image:    -moz-linear-gradient(top, #D0D0D0, #EBEBEB);    background-image:     -ms-linear-gradient(top, #D0D0D0, #EBEBEB);    background-image:      -o-linear-gradient(top, #D0D0D0, #EBEBEB);    background-image:         linear-gradient(top, #D0D0D0, #EBEBEB);}

使用说明:

PageTag.tld放在WEB-INF目录下
引入
<%@taglib uri=”/MyPageTag” prefix=”Mytaglib”%>
page.css
调用
<Mytaglib:Pagination pagination="PageUtil" divId="divId" href="Action"/>