jsp自定義分頁標簽


首先聲明我也是參考了在Struts2中實現自定義分頁標簽全攻略(一)后才寫的此文,做了點小改動,非原創也非抄襲,只是記錄下學習的過程。源碼在jar包中,最后有鏈接。

首先看看分頁的效果圖吧,

然后開始標簽的開發。

第一步,先創建一個tld文件,這個文件的作用是定義標簽,表明標簽的名字,處理類,引用URI還有屬性等信息。此文件放在/WEB-INF/下。

pager.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">
    
    <tlib-version>1.0</tlib-version>
    <short-name>pager</short-name>
    <uri>http://page.way2a.com/tag</uri>
    <tag>
        <!-- 標簽名 -->
        <name>page</name>
        <!-- 對應的標簽處理類 -->
        <tag-class>com.way2a.common.util.PageTag</tag-class>
        <!-- 標簽主體類型 -->
        <body-content>empty</body-content>
        <!-- 標簽屬性描述 -->
        <attribute>
            <!-- 屬性名  當前頁數 -->
            <name>pageNo</name>
            <!-- 是否是必須的 -->
            <required>true</required>
            <!-- 設置屬性的值是否可以在jsp編譯時動態生成 -->
            <rtexprvalue>true</rtexprvalue>
            <!-- 屬性的數據類型 -->
            <type>int</type>
        </attribute>
        <attribute>
            <!-- 總記錄條數 -->
            <name>totalRecord</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
            <type>int</type>
        </attribute>
        <attribute>
            <!-- 每頁展示的條數 -->
            <name>pageSize</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
            <type>int</type>
        </attribute>
        <attribute>
            <!-- 點擊分頁鏈接后跳轉的地址 -->
            <name>url</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
            <type>String</type>
        </attribute>
    </tag>    
</taglib>

第二步,根據上面tld文件的<tag-class>標簽創建標簽處理類 com.way2a.common.util.PageTag.java

package com.way2a.common.util;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

/**
 * 分頁標簽處理類
 * @author way2a
 *
 */
public class PageTag extends TagSupport{
    private static final long serialVersionUID = 6179314241821348095L;
    
    private int pageNo = 1;
    private int pageSize = 10;
    private int totalRecord ;
    private String url;
    
    @Override
    public int doStartTag() throws JspException {
        if(pageSize <= 0){
            pageSize = 10;
        }
        //計算總的頁數
        int pageCount = (totalRecord % pageSize == 0)?(totalRecord / pageSize):(totalRecord / pageSize + 1);
        //設置最多能顯示多少個頁數按鈕
        int maxShowButton = 5;
        
        StringBuilder sb = new StringBuilder();
        //拼接分頁樣式
        sb.append("<style type=\"text/css\">");
        sb.append(".pagination {clear:both;color:#323232;padding: 10px;float:right;font-size:13px;}");  
        sb.append(".pagination a, .pagination a:link, .pagination a:visited {padding:2px 5px;margin:2px;border:1px solid #b5b5b5;text-decoration:none;color:#006699;}");  
        sb.append(".pagination a:hover, .pagination a:active {background:#fff; text-decoration:none;}");  
        sb.append(".pagination span.current {padding: 2px 5px;margin: 2px;border: 1px solid #b5b5b5;font-weight: bold;background-color: #fdfdfd;box-shadow:1px 4px 6px rgba(0,0,0,0.2) inset;}");  
        sb.append(".pagination span.disabled {padding: 2px 5px;margin: 2px;border: 1px solid #eee; color: #ddd;}");  
        sb.append("</style>\r\n"); 
        
        if(this.totalRecord == 0){
            sb.append("<div style=\"width:100%;text-align:center;display:block;font-size:15px;\" >\r\n");
            sb.append("<Strong>沒有可顯示的項目</Strong>\r\n");
        }else{
            sb.append("<div class=\"pagination\" >\r\n");
            //對頁數進行越界處理
            if(pageNo > pageCount){
                pageNo = pageCount;
            }
            if(pageNo < 1){
                pageNo = 1;
            }
            
            sb.append("<form method=\"post\" action=\"").append(this.url)
                .append("\" name=\"paramForm\">\r\n");
            
            //獲取當前頁面request里的所有請求參數
            HttpServletRequest request = (HttpServletRequest)this.pageContext.getRequest();
            Enumeration<String> paramNames = request.getParameterNames();
            //遍歷枚舉里面的參數,與分頁有關的直接設置到屬性上,其他參數放置到type為hidden的input中
            String name = null;
            String value = null;
            while(paramNames.hasMoreElements()){
                name = paramNames.nextElement();
                value = request.getParameter(name);
                
                if("pageNo".equals(name)){
                    if(value != null && !"".equals(value)){
                        this.pageNo = Integer.parseInt(value);
                    }
                }else {
                    sb.append("<input type=\"hidden\" name=\"").append(name)
                        .append("\" value=\"").append(value).append("\" />\r\n");
                }
            }
            sb.append("<input type=\"hidden\" name=\"").append("pageNo")
                .append("\" value=\"").append(this.pageNo).append("\" />\r\n");
            
            sb.append("</form>\r\n");
            
            sb.append("<a href=\"javascript:turnOverPage(").append(1)
                .append(")\">首頁</a>\r\n");
            //當前頁面為第一頁時不顯示上一頁
            if(pageNo == 1){
                sb.append("<span class=\"disabled\">上一頁</span>\r\n");
            }else {
                sb.append("<a href=\"javascript:turnOverPage(").append(this.pageNo -1)
                    .append(")\" >上一頁</a>\r\n");
            }
            
            //設置顯示按鈕的數量
            int showButton = maxShowButton;
            //當頁數不夠maxShowButton時
            if(pageCount < maxShowButton){
                showButton = pageCount;
            }
            
            //標識顯示的按鈕上的開始下標
            int startPageIndex = 1;
            //當頁數為第一頁或第二頁時
            if(this.pageNo ==1 || this.pageNo ==2){
                startPageIndex = 1;
            }else{
                startPageIndex = this.pageNo - 2;
            }
            
            //當頁數為倒數第一或第二頁時    6 7 8 [9] 10   6 7 8 9 [10]  其他都是從當前頁面的前2個開始,展示maxShowButton個.
            //當總頁數不足maxShowButton時也適用,因為此時showButton等於pageCount,開始下標一直為1.
            if(this.pageNo == pageCount || this.pageNo == pageCount - 1 ){
                startPageIndex = pageCount - showButton + 1;  
            }
            
            //循環將按鈕拼接到HTML上
            for (int i = 0; i < showButton; i++) {
                int pageIndex = startPageIndex++;
                //如果是當前頁,則改變樣式,不可點擊。
                if(pageIndex == this.pageNo){
                    sb.append("<span class=\"current\">").append(pageIndex).append("</span>\r\n");
                }else{
                    sb.append("<a href=\"javascript:turnOverPage(").append(pageIndex).append(")\">").append(pageIndex).append("</a>\r\n");
                }
            }
            //如果到達了最后一頁,則下一頁按鈕不可用
            if(this.pageNo == pageCount){
                sb.append("<span class=\"disabled\">下一頁</span>\r\n");
            }else{
                sb.append("<a href=\"javascript:turnOverPage(").append(this.pageNo + 1)
                    .append(")\" >下一頁</a>\r\n");
            }
            
            sb.append("<a href=\"javascript:turnOverPage(").append(pageCount)
                .append(")\">末頁</a>\r\n");
            //拼接總記錄條數和總頁數
            sb.append("共<strong>").append(this.totalRecord).append("</strong>條,").append("共<strong>")
                .append(pageCount).append("</strong>頁");
            
            sb.append("<script type=\"text/javascript\">\r\n");
            sb.append("function turnOverPage(no){\r\n");
            sb.append("if(no>").append(pageCount).append("){");
            sb.append("no=").append(pageCount).append(";}\r\n");
            sb.append("if(no<1){ no=1;}\r\n");
            sb.append("document.paramForm.pageNo.value=no;\r\n");
            sb.append("document.paramForm.submit();\r\n");
            sb.append("}\r\n");
            sb.append("</script>\r\n");
        }
        sb.append("</div>\r\n");
        
        try {
            this.pageContext.getOut().println(sb.toString());
        } catch (IOException e) {
            throw new JspException(e);
        }
        return 0;
    }

    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 getTotalRecord() {
        return totalRecord;
    }

    public void setTotalRecord(int totalRecord) {
        this.totalRecord = totalRecord;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

 這個java類會在引用了這個標簽的地方輸出HTML代碼替換掉標簽。

第三步,在jsp頁面頭部引入標簽

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://page.way2a.com/tag" prefix="pager" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head><title></title></head>
  
  <body>
    <h2>hello</h2>
    <pager:page pageSize="10" pageNo="1" url="/PageTag/HelloServlet" totalRecord="200"/>
  </body>
</html>

 由於只是演示,就把參數寫死了,實際中用${}獲取request中相應的參數值。

然后說個問題,我在ssm項目中使用時發現,url參數這里填寫<%=contextPath%>/xxx/xxx時,訪問頁面會報錯,org.apache.jasper.JasperException:attribute value for [url] is not properly terminated。

上網查了后發現好像這里不能用<%=xxx%>與/xxx混合,要么使用純字符串路徑 xxx/xxx,要么只用表達式<%=url%>。應該是不支持解析表達式值后再拼接字符串。

還有一個點就是點擊頁數按鈕使用的是表單post提交,所以@RequestMapping()不要寫method=RequestMethod.GET,否則報405。

 到這里就開發完了,但是如果每個項目要用到都去建這個類和tld文件顯然是很麻煩的,因此只需要把這個class文件和tld文件放到classpath上就行了,可以打包成一個jar包。

tld文件放在META-INF文件夾,然后cmd中進入到所在文件夾下,使用以下命令進行打包:jar -cvf xxx-xxx.jar *

最后把我的jar包放上來給有需要的人參考下。

鏈接: https://pan.baidu.com/s/1o76RFHw 密碼: 7fh8


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM