Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30465850
  • 博文数量: 708
  • 博客积分: 12163
  • 博客等级: 上将
  • 技术积分: 8240
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-04 20:59
文章分类

全部博文(708)

分类: Java

2008-04-03 11:02:54

自定义分页标签库

1:在配置文件中配置
<!-- self Tag Library Descriptors -->
  <taglib>
    <taglib-uri>/WEB-INF/self-html.tld</taglib-uri>
    <taglib-location>/WEB-INF/self-html.tld</taglib-location>
  </taglib>
2:在self-html.tld中page标签的配置
<tag>
        <name>page</name>
        <tagclass>com.jbbis.netedu.common.util.taglib.PageTag</tagclass>
        <bodycontent>empty</bodycontent>
        <info>tag here</info>
        <attribute>
        <name>name</name>
        <required>true</required>
        <rtexprvalue>false</rtexprvalue>
        </attribute>
        <attribute>
        <name>pageNum</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
        </attribute>
        <attribute>
        <name>method</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
        </attribute>
        <attribute>
        <name>methodValue</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
        <name>form</name>
        <required>true</required>
        <rtexprvalue>false</rtexprvalue>
        </attribute>
        <attribute>
        <name>action</name>
        <required>flase</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
        <name>returnLevel</name>
        <required>flase</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
其实从这儿也可以看到在PageTag文件中是一些什么值了...

3:PageTag中的具体操作(精华全部在这儿啦)
/**//*
 * Created on 2004-6-25
 *
 */

package com.jbbis.netedu.common.util.taglib;

import java.io.IOException;

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

import com.jbbis.netedu.common.page.NullPage;
import com.jbbis.netedu.common.page.Page;

/** *//**
 * @author leo_deng
 *
 */

public class PageTag extends TagSupport {
    

    /**//* (non-Javadoc)
     * @see javax.servlet.jsp.tagext.Tag#doStartTag()
     */

    private String name;
    private String pageNum="pageNum";
    private String method="method";
    private String methodValue;
    private String form="mainForm";
    private String action;
    private String returnLevel;
    
    private final int CONST_FIRST=1;
    private final int CONST_NEXT=2;
    private final int CONST_PRIOR=3;
    private final int CONST_LAST=4;
    
    
    
    
    public int doStartTag() throws JspException {
        // TODO Auto-generated method stub

        try{
            JspWriter out = pageContext.getOut() ;
            Page page=(Page)pageContext.getRequest().getAttribute(name);
            if(page==null)
                page=NullPage.instance();
            out.print(getHtml(page.getPageNumber(),page.getPageCount()));
            out.print(getJs(page.getPageNumber(),page.getPageCount()));
            //jspwriter是一个隐含对象,用于向jsp网页输出内容。输出的目标由

            // pagecontext.getout提供

            
            //向jsp网页上下文输出

          }catch(IOException ioException){
            throw new JspException(ioException.getMessage() );
          }//catch

          return(SKIP_BODY);
    }
    /**//*
     * <
     *
     *


            首页
            上页
            第
            下页
            末页
            共 1000
        

     *
     * */
    private String getJs(int pageNum,int totalNum){
        StringBuffer sb=new StringBuffer();
        sb.append("\n");

        return sb.toString();
    }
    private void getGoJs(StringBuffer sb,int pageNum,int totalNum){
        sb.append("function page_go(obj){\n");
        sb.append("var page_number=document.getElementById(\"page_number\");\n");
        sb.append("if( page_number.value != new Number(page_number.value))return alert(\"请输入正确的页数\");\n");
        sb.append("if(page_number.value<1) page_number.value=1;if(page_number.value>");
        sb.append(totalNum);
        sb.append(")page_number.value=");
        sb.append(totalNum);
        sb.append(";\n");
        sb.append("if(page_number.value!="+pageNum+")");
        sb.append("submitForPageNum(obj);\n");
        sb.append("}");
    }
    private StringBuffer printFunction(String function,int pageNumber,int totalNumber,int pageConst){
        StringBuffer sb=new StringBuffer();
        sb.append("\nfunction "+function+"(){");
        sb.append("\nevent.returnValue=false;");
        sb.append(printAction());
        sb.append(printMethod());
        //sb.append("\n"+this.form+".submit();\n}");

        if(totalNumber>1){
            switch(pageConst){
                case CONST_FIRST:
                    if(pageNumber>1){
                        sb.append(printPageNum(String.valueOf(1)));
                        sb.append("\n submitForPageNum("+this.form+");");
                    }
                    break;
                case CONST_LAST:
                    if(pageNumber<totalNumber){
                        sb.append(printPageNum(String.valueOf(totalNumber)));
                        sb.append("\n submitForPageNum("+this.form+");");
                    }
                    break;
                case CONST_PRIOR:
                    if(pageNumber>1){
                        sb.append(printPageNum(String.valueOf(pageNumber-1)));
                        sb.append("\n submitForPageNum("+this.form+");");
                    }
                    break;
                case CONST_NEXT:
                    if(pageNumber<totalNumber){
                        sb.append(printPageNum(String.valueOf(pageNumber+1)));
                        sb.append("\n submitForPageNum("+this.form+");");
                    }
                    break;
            }
        }
        
        sb.append("\n}");
        return sb;
    }
    /**//*
    private StringBuffer printFunction(String function,String pageNum,int pageConst){
        StringBuffer sb=new StringBuffer();
        sb.append("\nfunction "+function+"(){");
        sb.append("\nevent.returnValue=false;");
        sb.append(printAction());
        sb.append(printMethod());
        sb.append(printPageNum(pageNum));
        //sb.append("\n"+this.form+".submit();\n}");

                
                sb.append("\n submitForPageNum("+this.form+");\n}");

        
        sb.append("\n}");
        
        return sb;
    }
    */

    private String printAction(){
        if(this.action!=null)
            return ("\n"+this.form+".action=\""+action+"\";");
        else
            return "";
    }
    private String printMethod(){
        if(this.methodValue!=null)
            return ("\n"+this.form+"."+this.method+".value=\""+this.methodValue+"\";");
        else
            return "";
    }
    private String printPageNum(String num){
        return "\n"+this.form+"."+this.pageNum+".value=\""+num+"\";";
    }
    private String getHtml(int pageNum,int totalNum){
        StringBuffer sb=new StringBuffer();
        sb.append("\n\"首页\"");
        sb.append("\n\"上页\"");
        sb.append("\n第);
        sb.append(String.valueOf(pageNum));
        sb.append("\">页 ");
        //sb.append(""");

        sb.append("\n\"下页\"");
        sb.append("\n\"末页\"");
        sb.append("\n共 ");
        sb.append(String.valueOf(totalNum));
        sb.append(" 页"
);
        return sb.toString();
    }

    /** *//**
     * @return Returns the pageNum.
     */

    public String getPageNum() {
        return pageNum;
    }
... ....(other getter and setter method ^_^)
}

4:在JSP布面中导入:
<%@ taglib uri="/WEB-INF/self-html.tld" prefix="netedu" %>
5:在JSP页面中引用:
<form name="newsForm" method="post" action="<%=request.getContextPath() %>/portal/newsAction.page" id="newsForm">
<!-- TIP008:
  翻页部分
 -->
   <div class="listbox_page">
    <netedu:page name="page" form="newsForm" />
   </div>
<!-- TIP008:END-->
 </form>
6:page文件

/**//*
 * Created on 2004-6-8
 */

package com.jbbis.netedu.common.page;

import java.util.Collection;


/** *//**
 * 分页表示 Bean
 * 用于前台显示分页数据
 * @author qqs
 */

public interface Page {

  /** *//**
   * whether or not is the last page of list data
   * 是否为最后一页
   * @return
   */

  public boolean isLast();

  /** *//**
   * 是否为第一页
   * @return
   */

  public boolean isFirst();

  /** *//**
   * List of page data
   * @return Page data
   */

  public Collection getData();
  
  /** *//**
   * List of page data
   * @return Page data
   */

  public void setData(Collection data);

  /** *//**
   * 当前页数
   * @return Page Number
   */

  public int getPageNumber();

  /** *//**
   * Next page number
   * if current page is the first page then
   * return 0;
   * else
   * return pageNumber+1;
   * 下一页的页数
   *
   * @return next page number
   */

  public int getNextPageNumber();

  /** *//**
   * 前一页的页数
   * if previous pge lest than last the first page then
   * return 0
   * esle
   * return PageNumber - 1
   * @return previous page number
   */

  public int getPrevPageNumber();

  /** *//**
   * Current page size
   * 当前页的记录数
   * @return Current page size
   */

  public int getSize();

  /** *//**
   * Page size
   * 定义的每页的页数
   * @return
   */

  public int getPageSize();
  /** *//**
   * Total pages count
   * 总页数
   * @return Total pages count
   */

  public int getPageCount();

  /** *//**
   * 当前页中第一条记录在数据库中的顺序
   * get index of the first data of the page
   * @return index of the first data of the page
   */

  public int getStartIndex();

  /** *//**
   * get index of the last data of the page
   * 当页的最后一条记录在数据库中的顺序
   * @return index of the first data of the page
   */

  public int getEndIndex();

  /** *//**
   * 总的记录数
   * @return
   */

  public int getTotalSize();

  /** *//**
   * 是否为空页
   * @return
   */

  public boolean isNull();
}
7:其它
7.1
可以注意到在标签的定义文件中用到了名为page_go的css层来美化界面,可能是出于满足不同用户对界面的不同要求所以在此没有对此css定义,你可以在JSP布面中重写此css.这儿有个可以参考一下.下载
7.2
根据标签的定义可以看到,此page应该放到form中.
7.3
根据在标签库中的
Page page=(Page)pageContext.getRequest().getAttribute(name);
语句,可见page应该在request.setAttribute("pageattribute",page);中定义.

7.4
如何通过对DB的操作得到了page ?通过DB操作可以获得一系统的data(应该注意到了在page文件夹中有个data属性,高人就是高人^_^),当然在得到这些data之前,先可能得进行一系统逻辑处理,比如说当前页码(pagenum),页长(pagesize)等等. ~ ~ : )

我们在action中:

 // JSP中引用此attribute分页处理

 
request.setAttribute( " page " ,page);
然后在JSP中引用此page。
这次主要看如何能过对DB操作实现此page。

处理逻辑:
1:根据SQL语句,当前页面,页面大小等参数,得到一系统data。
2:根据得到的data,再加上当前页面,页面大小可以实例化一个page类实体。
3:将此实体转换成便于到前台显示的DTO。

具体如下:

首先,我们根据查询语句从DB中得到一系列相关数据

......

Query query = getSession().createQuery(sql);
            setParams(query, paramNames, params);
            if (pageSize > -1) {
                query.setFirstResult(PageManager.getStartIndex(pageNumber,
                        totalCount, pageSize));
                query.setMaxResults(pageSize);
            }
            List data = doQuery(query);
            
            if (pageSize < 0) {
                totalCount = data.size();
            }

......
可以看到其中除了createQuery,setFirstResult,setMaxResults外其实都是用户自定义的一些函数。
其它函数,顾名思义应该知道它想实现一个什么功能,象doQuery(query)就是得到一个结果集也许是得到一个按列表方式抽取结果集 query.list(),or 按迭代方式抽取结果集query.iterate().函数getStartIndex(args[])返回数据第一条记录的起点位置。其它的也都差不多!

其次得到一个page的实体类(entity),或者说得到其DAO对象。
其实得到一个DTO的page对象比较简单。前面列出了page,而上面已经从DB中得到了一系列数据(data),再加上页面的相关信息就可以实例化一个page实体了:

 .

 public DefaultPage( int pageSize, int pagesCount, int pageNumber, Collection data,
                      int totalSize) {
     this .pageSize = pageSize;
     this .pagesCount = pagesCount;
     this .pageNumber = pageNumber;
     this .totalSize = totalSize;
     this .data = data;
  }
 
 .
当然在此前,对面页数据得处理一下,象pageNumber可能如下:

  /** */ /**
     * @param pageNumber
     * @param pageSize
     * @param totalCount
     * Return PageNumber
      */

      protected static int calcPageNumber( int pageNumber, int pageSize, int totalCount) {
         int maxPageNumber = calcMaxPageNumber(pageSize, totalCount);
        
        pageNumber = pageNumber > maxPageNumber ? maxPageNumber:pageNumber;
        
         if (pageNumber <= 0 )
            pageNumber = 1 ;
        
         return pageNumber;
    }
easy吧!

最后将此实体转换成适合前台显示的DTO对象。
这个侧是依据不同的需求去做相应的转换了,一般来说从DB取出来的实体(DAO)直接与DB中的数据对应。而在DTO中我们可以提供许多更加符合实际的字段与方法,使得我们的JSP页面显示更加得心应手!同时也避免了直与DB交互。它们之间的关系, 我乱七八糟写过些东西(欢迎指正!)。

“一般人的标签我不看,高手写的东西真的值得借鉴,学习!”

阅读(1052) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~