• 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>
    "); 
            
            if(this.totalRecord == 0){
                sb.append("<div style="100%;text-align:center;display:block;font-size:15px;" >
    ");
                sb.append("<Strong>没有可显示的项目</Strong>
    ");
            }else{
                sb.append("<div class="pagination" >
    ");
                //对页数进行越界处理
                if(pageNo > pageCount){
                    pageNo = pageCount;
                }
                if(pageNo < 1){
                    pageNo = 1;
                }
                
                sb.append("<form method="post" action="").append(this.url)
                    .append("" name="paramForm">
    ");
                
                //获取当前页面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("" />
    ");
                    }
                }
                sb.append("<input type="hidden" name="").append("pageNo")
                    .append("" value="").append(this.pageNo).append("" />
    ");
                
                sb.append("</form>
    ");
                
                sb.append("<a href="javascript:turnOverPage(").append(1)
                    .append(")">首页</a>
    ");
                //当前页面为第一页时不显示上一页
                if(pageNo == 1){
                    sb.append("<span class="disabled">上一页</span>
    ");
                }else {
                    sb.append("<a href="javascript:turnOverPage(").append(this.pageNo -1)
                        .append(")" >上一页</a>
    ");
                }
                
                //设置显示按钮的数量
                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>
    ");
                    }else{
                        sb.append("<a href="javascript:turnOverPage(").append(pageIndex).append(")">").append(pageIndex).append("</a>
    ");
                    }
                }
                //如果到达了最后一页,则下一页按钮不可用
                if(this.pageNo == pageCount){
                    sb.append("<span class="disabled">下一页</span>
    ");
                }else{
                    sb.append("<a href="javascript:turnOverPage(").append(this.pageNo + 1)
                        .append(")" >下一页</a>
    ");
                }
                
                sb.append("<a href="javascript:turnOverPage(").append(pageCount)
                    .append(")">末页</a>
    ");
                //拼接总记录条数和总页数
                sb.append("共<strong>").append(this.totalRecord).append("</strong>条,").append("共<strong>")
                    .append(pageCount).append("</strong>页");
                
                sb.append("<script type="text/javascript">
    ");
                sb.append("function turnOverPage(no){
    ");
                sb.append("if(no>").append(pageCount).append("){");
                sb.append("no=").append(pageCount).append(";}
    ");
                sb.append("if(no<1){ no=1;}
    ");
                sb.append("document.paramForm.pageNo.value=no;
    ");
                sb.append("document.paramForm.submit();
    ");
                sb.append("}
    ");
                sb.append("</script>
    ");
            }
            sb.append("</div>
    ");
            
            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

    如有错误,欢迎大家指正,共同进步。
  • 相关阅读:
    FXML Stuffs (include and define)
    javaFX中解决填充(拉伸)问题
    <转>用 Java 技术创建 RESTful Web 服务
    webservice restful一个小例子
    《转》理解restful
    webservice之restlet实现
    WebService:CXF-SPRING 读书笔记
    PHP 单链表
    php 读xml的两种方式
    php输出金字塔
  • 原文地址:https://www.cnblogs.com/deng720/p/7736604.html
Copyright © 2020-2023  润新知