自定义分页标签儿

这个前面也就是匆匆带过了,还是好好描述一番吧。

什么是自定义标签儿。就是在jsp页面中,我们自己生成定义的标签儿,可以处理一定的逻辑。所以本质上还是要有java代码来处理的。

自定义标签儿能够运行的三个要素:

1、对应的java处理程序。

2、tld标签儿语言定义

3、在.jsp文件中导入包儿,并且,在页面中使用。

那么在3中得到导入路径,通过3知道对应的tld文件,那么一定是在tld中有对应的java包的引入。这样三者构成一种连接关系,那么代码就能执行了。

下面以分页为例,来简单阐述这个自定义标签儿。

从页面开始:

效果:

标签儿部分:

<p align="center">
        <page:page pageSize="${pageBean.pageSize }" historical="" method="" url="BookServlet.do" currentPage="${pageBean.currentPage }" count="${pageBean.count }"/>
    </p>

引入部分:

<%@ taglib uri="http://com.letben.tag" prefix = "page" %>

接下来要通过这个 uri找到tld文件。

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee "
    version="2.1">

  <description>pageTag</description>
  <display-name>pageTag</display-name>
  <tlib-version>1.1</tlib-version>
  <short-name>letben</short-name>
  <uri>http://com.letben.tag</uri><!-- 在这里就发现了,这个路径,那么就可以通过前面页面里的uri找到这个tld文件。 -->

  <tag>
      <name>page</name>
      <tag-class>com.letben.tag.PageTag</tag-class><!-- 发现这个文件能够对应到一个 PageTag的包。 -->
      <body-content>empty</body-content>
      <attribute>
          <name>currentPage</name><!-- 标签儿中出现的属性名 -->
          <required>true</required><!-- 是否必须出现,是,由于这里面当时忘记了,这个的存在,导致在后面的项目在使用ssh框架的时候,多写了三个属性以及对应的get 和set方法。private String historical,private String method,和什么吧,忘记了,主要是因为 这些属性在只使用servlet开发的时候,这些东西还是有必要给上的,但是在ssh框架里面不再需要了,所以 多写了这样一些没有用的属性和方法。-->
          <rtexprvalue>true</rtexprvalue><!-- 是否允许值的改写,是 -->
      </attribute>
      <attribute>
          <name>count</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
          <name>pageSize</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
          <name>url</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
          <name>historical</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
          <name>method</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
      </attribute>
  </tag> 

 </taglib>

这样到PageTag里面,去看看究竟。

package com.letben.tag;

import java.io.IOException;
import java.text.MessageFormat;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

public class PageTag extends TagSupport {

    private int count=0;
    private int currentPage=1;
    private int pageSize = 5;
    private String url;
    private String method;
    private String historical;

    public String getMethod() {
        return method;
    }
    public void setMethod(String method) {
        this.method = method;
    }
    public String getHistorical() {
        return historical;
    }
    public void setHistorical(String historical) {
        this.historical = historical;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
    public int getCurrentPage() {
        return currentPage;
    }
    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public int doStartTag() throws JspException {

        int totalPage = count%pageSize==0?count/pageSize:count/pageSize+1;
        if(currentPage<=1){
            currentPage = 1;
        }
        if(currentPage>=totalPage){
            currentPage = totalPage;
        }
        //<a href="BookServlet.do?page=3&historical=yes&method=somehow" >超级链接</a>
        String linkPattern = "<a href=\"{0}?page={1}&historical={3}&method={4}\">{2}</a>";
        String first = MessageFormat.format(linkPattern, url,1,"首页",historical,method);//<a href=bookservlet.do?page=1&historical=yes&method=add>首页</a>
        String pre = MessageFormat.format(linkPattern, url,currentPage-1,"上一页",historical,method);
        String next = MessageFormat.format(linkPattern,url,currentPage+1,"下一页",historical,method);
        String last = MessageFormat.format(linkPattern, url,totalPage,"尾页",historical,method);
        if(currentPage<=1){
            first = "首页";
            pre = "上一页";
        }
        if(currentPage>=totalPage){
            next = "下一页";
            last = "尾页";
        }
        String htmlString = "{0}&nbsp;{1}&nbsp;{2}&nbsp;{3}&nbsp;&nbsp;&nbsp;&nbsp;共&nbsp;{4}&nbsp;页,{5}&nbsp;条记录。当前第&nbsp;{6}&nbsp;页,分页单位是&nbsp;{7}&nbsp;条记录";
        //<a href=bookservlet.do?page=1&historical=yes&method=add>首页</a> &nbsp; <a href=bookservlet.do?page=1&historical=yes&method=add>下一页</a> &nbsp;
        //<a href=bookservlet.do?page=1&historical=yes&method=add>首页</a> &nbsp;
        htmlString = MessageFormat.format(htmlString, first,pre,next,last,totalPage,count,currentPage,pageSize);

        JspWriter out = this.pageContext.getOut();
        try {
            out.println(htmlString);
        } catch (IOException e) {
            System.out.println("输出标签时,出现异常");
            e.printStackTrace();
        }

        return this.EVAL_PAGE;
    }

}

发现doStartTag()还比较有用,就是 在页面,在生成当前标签儿之前,会执行这个·方法。回顾页面,页面要输出的就是一些超级链接。本质上就是一堆html代码。

那么要在这里把它拼接出来。然后通过 当前页得到输出流对象,把它打印到前台就好了。那么具体要打印什么,就需要里面接一下了。拼接方式 使用了一个字符串的拼接模板方式。

举个例子就是:String pattern = "my name is {0} my age is {1}";

String outString = MessageFormat.format(pattern,"lifei",23);

输出的结果就是: my name is lifei ma age is 23.

就这样一个 结果。所以如法炮制得到这样一个 分页 的htmlString。

还有效果更棒的哦,这个只是1.0版本,下面有一个 1.6版本的分页,十分稳定,主要是 字符串拼接有一些逻辑要格外注意。

期望样式,下面给了,并且也给出了每个版本修复的bug。

package com.letben.tag;

import java.io.IOException;
import java.text.MessageFormat;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

/**
 * PageTag 1.1 解决了,历史分页问题。
 * PageTag 1.2 尝试配出老师需要的模板,是个 过渡版本。存在严重bug!!!
 * PageTag 1.3 版本,并不存在十分严重bug。算法是对的。应用场景,有点儿小bug。忘了考虑上下几页的问题。
 * PageTag 1.4 版本,能够显示分页了。应该是 各种bug都没有了,并且 能很好地 显示分页。最后一页显示条目有bug。
 * PageTag 1.5 版本,必须各种bug没有了!!!。能够完美显示,并且最后一页有几条项目,就显示多少个条目。
 * PageTag 1.6 版本,消除了,未获得数据时,回报的by zero。异常。
 * PageTag 1.61 版本,多一个判非条件。之前仅一个 不合适,可能会存在异常。
 * @author RealisedBy : Letben  TaughtBy : Salmon  At Dec.16th
 */
public class PageTag extends TagSupport {

    private int count=0;
    private int currentPage=1;
    private int pageSize = 5;
    private String url;
    private String method;
    private String historical;

    public String getMethod() {
        return method;
    }
    public void setMethod(String method) {
        this.method = method;
    }
    public String getHistorical() {
        return historical;
    }
    public void setHistorical(String historical) {
        this.historical = historical;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
    public int getCurrentPage() {
        return currentPage;
    }
    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * 主要是 创建 标签这里需要一些技术。
     * 现在 样式   :首页 上一页 下一页 尾页    共 3 页,6 条记录。当前第 3 页,分页单位是 2 条记录
     * 期望样式    :首页 上一页 ... 7 8 9 10 11 12 ... 下一页 尾页 共1234条 每页显示 10/23
     */
    @Override
    public int doStartTag() throws JspException {
        /*
         * 现在 样式   :首页 上一页 下一页 尾页    共 3 页,6 条记录。当前第 3 页,分页单位是 2 条记录
         * 期望样式    :首页 上一页 ... 7 8 9 10 11 12 ... 下一页 尾页 共1234条 每页显示 10/23
         *
         * 修改点1:
         * 需要在 上一页 和 下一页中间加入一些内容。数字,如果页数大于5就有必要隐藏一些数据,如果页数小于5就展示所有信息。
         *
         * 修改点2:
         * 共 3 页,6 条记录。当前第 3 页,分页单位是 2 条记录
         * 共1234条 每页显示 10/23
         */
        JspWriter out = this.pageContext.getOut();//select * from user_tb where username like ‘%~%‘;
        if(pageSize==0||count==0){
            try {
                out.println("%>_<%,查找时,未获得数据哟~~~。【请更换查找条件 O(∩_∩)O ~~~】");
            } catch (IOException e) {
                System.out.println("未获得数据,输出标签时,出现异常");
                e.printStackTrace();
            }
            return this.EVAL_PAGE;
        }else{
            int totalPage = count%pageSize==0?count/pageSize:count/pageSize+1;
            if(currentPage<=1){
                currentPage = 1;
            }
            if(currentPage>=totalPage){
                currentPage = totalPage;
            }
            //<a href="BookServlet.do?page=3&historical=yes&method=somehow" >超级链接</a>

            //string pattern1 = wo de ming zi jiao {0} nian ling shi {1};
            // string str1 = messageFormat.format(pattern1,"lifei",23);
            //System.out.println(str1); --->  wo de ming zi jiao lifei nian ling shi 23;

            String linkPattern = "<a href=\"{0}?page={1}&historical={3}&method={4}\">{2}</a>";
            String first = MessageFormat.format(linkPattern, url,1,"首页",historical,method);
            String pre = MessageFormat.format(linkPattern, url,currentPage-1,"上一页",historical,method);
            String next = MessageFormat.format(linkPattern,url,currentPage+1,"下一页",historical,method);
            String last = MessageFormat.format(linkPattern, url,totalPage,"尾页",historical,method);
            if(currentPage<=1){
                first = "首页";
                pre = "上一页";
            }
            if(currentPage>=totalPage){
                next = "下一页";
                last = "尾页";
            }
            /*
                                                                 * 共 3 页,6 条记录。当前第 3 页,分页单位是 2 条记录
                                                                 * 共1234条 每页显示 10/23
             */
            String htmlString = "{0}&nbsp;{1}&nbsp;{7}{2}&nbsp;{3}&nbsp;&nbsp;&nbsp;&nbsp;共&nbsp;{4}&nbsp;条&nbsp;&nbsp;每页显示&nbsp{5}/{6}";

            String middle = getMiddleNumber(totalPage,currentPage);
            //System.out.println(middle);
            int showPageSize=0;
            if(currentPage!=totalPage){
                showPageSize = pageSize;
            }else{
                showPageSize = count-pageSize*(totalPage-1);
            }
            //System.out.println(showPageSize);

            htmlString = MessageFormat.format(htmlString, first,pre,next,last,count,showPageSize,count,middle);
            //System.out.println(htmlString);

            try {
                out.println(htmlString);
            } catch (IOException e) {
                System.out.println("输出标签时,出现异常");
                e.printStackTrace();
            }

            return this.EVAL_PAGE;

        }

    }
    /**
     * 拼接中间的那对数字的代码
     * @param totalPage
     * @param currentPage
     * @return
     */
    private String getMiddleNumber(int totalPage,int currentPage) {
        //System.out.println(currentPage);
        //  TODO 这也是个bug    首页 上一页 1 下一页 尾页    共 1 条  每页显示 2/1 当只有一个 用户的时候。
        // 如果真的老板丧心病狂,把 用户 一个一个 都删了,这就会出问题,
        // 如果 此时 有人直接 动了 数据库,删除了当前用户,根据 session他仍然能够 登录,这也是个 bug。
        // TODO
        //<a href="BookServlet.do?page=3&historical=yes&method=somehow" >超级链接</a>
        String linkPattern = "<a href=\"{0}?page={1}&historical={3}&method={4}\">{2}</a>";
        String[] strings = null;
        StringBuffer sb=null;
        if(totalPage<=0){
            //如果条目数<=0的话
            //如果系统能够登录,只少有一个 用户,那么就不用做,为0判断。
            System.out.println("没有记录可以被显示");
        }else{// 否则 count一定有值
            //否则count 一定大于0.
            if(totalPage>5){
                strings = new String[5];
            }else{
                strings = new String[totalPage];
            }
            String string=null;
            //if(totalPage<=5){//1-5
                //string =MessageFormat.format(linkPattern,url,count,count,historical,method);
                //strings[count-1]=string;
            int times = 0;
            if(totalPage<=5){
                times=totalPage;
            }else {
                times=5;
            }
            if(totalPage<=5){//1,2,3,4,5
                for(int i=1;i<=times;i++){
                    if(i==currentPage){
                        string = i+"";
                        strings[i-1]=string;
                        //System.out.println(string);
                    }else{
                        string = MessageFormat.format(linkPattern, url,i,i,historical,method);
                        strings[i-1]=string;
                        string=null;
                    }
                }
            }else{//6,7,8……
                int middle=0;
                if(currentPage<3){
                    middle=3;
                }else if(currentPage+2>totalPage){
                    middle = totalPage-2;
                }else {
                    middle = currentPage;
                }

                for(int i=middle-2,j=0;i<=middle+2;i++,j++){
                    if(i!=currentPage){
                        string = MessageFormat.format(linkPattern, url,i,i,historical,method);
                        //System.out.println(i);
                        //System.out.println(j);//调皮的bug,我不输出你,你都不老老实实执行!!!,这应该是 历史上第三次了,之前事件监听里面有一回。
                        //System.out.println(string);
                        //System.out.println(strings.length);
                        strings[j] = string;
                        string = null;
                    }else {
                        string = i+"";
                        strings[j]=string;
                        string=null;
                    }
                }
            }
            //}
            /*else if(totalPage>5){
                //如果>5的话,是不是要显示中间的五个
                //首页 上页   2 3 4 5 6 下页 尾页   ***
                int middle=0;
                if(currentPage<3){
                    middle=3;
                }else if(currentPage+2>totalPage){
                    middle = totalPage-2;
                }else {
                    middle = currentPage;
                }
                for(int i=middle-2;i<=middle+2;i++){
                    string = MessageFormat.format(linkPattern, url,i,i,historical,method);
                    strings[i-1] = string;
                    string = null;
                }
            }*/
            sb = new StringBuffer();
            for(int i=0;i<strings.length;i++){
                sb.append(strings[i]);
                sb.append("&nbsp;");
            }
            if(totalPage>5){
                if(currentPage>3){
                    sb.insert(0, "……");
                }
                if(currentPage+2<totalPage){
                    sb.append("……");
                }

            }
        }
        return sb.toString();
    }
}
时间: 2024-10-07 05:57:19

自定义分页标签儿的相关文章

JSP自定义分页标签TAG

首先我们需要在WEB-INF/tld/目录下创建page.tld文件 <?xml version="1.0" encoding="ISO-8859-1"?> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>page</short-name> <u

SSH自定义分页标签

本文参考文章:http://blog.csdn.net/qjyong/article/details/3240303 一.标签处理类: package cn.conris.sys.form; import java.io.IOException; import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspException; import java

jsp自定义分页标签

1.web工程的整体结构 2.Eclipse中tld文件的构建方法3.编码 package mytags; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; public class PagerTag extends TagSupport { /** * */ private static final long serialV

自定义分页标签步骤

1.引架包 <!--javaee,处理自定义标签--> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> 2.在WEB-INF中创建.tld.文件,加入需引用

NET Core-TagHelper实现分页标签

1.继承父类TagHelper并重写Process方法(这里还有一个异步的方法ProcessAsync各位可以自己尝试下) 2.注意:怎么在试图页面使用自定义标签 3.注意:怎么识别标签中的属性 4.注意:自定义标签类怎么获取分页参数 5.效果展示 下面一步一个脚印的来分享: 1.继承父类TagHelper并重写Process方法(这里还有一个异步的方法ProcessAsync各位可以自己尝试下) 首先咋们定义一个类取名为PagerTagHelper,这里需要继承TagHelper类,重写Pro

python/Djangof分页与自定义分页

python/Djangof分页与自定义分页 Django分页 1 ##============================================分页======================================================= 2 # current_pagc = request.GET.get('page') 3 # from django.core.paginator import Paginator,Page 4 # # result = m

Django自定义分页、bottle

一.使用django实现之定义分页 1.自定义分页在django模板语言中,通过a标签实现; 2.前段a标签使用<a href="/user_list/?page=1">1</a>,将page的值传送到函数/user_list/中,后端在user_list中通过request.GET.get('page',1)获取当前页; 3.从数据库中获取特定行的数据,使用result = models.UserList.objects.all()[start:end]获取,

Python之路【第十九篇】自定义分页实现(模块化)

自定义分页 1.目的&环境准备 目的把分页写成一个模块的方式然后在需要分页的地方直接调用模块就行了. 环境准备Django中生成一个APP并且注册,配置URL&Views 配置URL from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^user_lis

Android入门之ActivityGroup + GridView 实现Tab分页标签

很多客户端软件和浏览器软件都喜欢用 Tab 分页标签来搭建界面框架.读者也许会马上想到使用 TabHost 与 TabActivity 的组合,其实最常用的不是它们,而是由 GridView 与 ActivityGroup 的组合.每当用户在 GridView 选中一项, ActivityGroup 就把该项对应的 Activity 的 Window 作为 View 添加到 ActivityGroup 所指定的容器 (LinearLayout) 中. 接下来贴出本例运行的效果图 : ImageA