Struts2自定义分页标签

    最近在学习Struts2,并使用Struts2开发系统。在网上看了好多的struts2的分页,虽然都实现了分页的功能,但是感觉不是非常好,需要我们在每次写分页的时候做很多的工作,而我认为分页应该是一个通用的组件,开发人员在开发的过程中不应该在分页上花费太多的精力。所以,一直想封装一个比较通用的分页组件,而设计分页组件的时候,怎样保证动态查询的参数不丢失,成为实现的一个难点。感谢tangshuo和shim的分享,让我实现了这样的一个分页组件。
         该组件采用自定struts2标签的方式实现。
         首先建立一个构建分页标签信息的类:Pages.java
/**
  * 构建分页标签体的类
  * @date 2008 - 11 - 4 下午 02:52:19
  * @version 1.0
  */

Pages.java

package com.oaapp.tag;

import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.StrutsStatics;
import org.apache.struts2.components.Component;
import org.apache.struts2.dispatcher.StrutsRequestWrapper;

import com.oaapp.util.Util;
import com.opensymphony.xwork2.util.ValueStack;

public class Pages extends Component {
    private HttpServletRequest request;    
    private String pageNo;   //当前页码
    private String total;   //总页数
    private String styleClass;   //分页的样式
    private String theme;   //分页的主题
    private String url;   //action的路径
    private String urlType; //路径的类型,主要用于URL重写的扩展
            
    public HttpServletRequest getRequest() {
        return request;
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    public String getPageNo() {
        return pageNo;
    }

    public void setPageNo(String pageNo) {
        this.pageNo = pageNo;
    }

    public String getTotal() {
        return total;
    }

    public void setTotal(String total) {
        this.total = total;
    }

    public String getStyleClass() {
        return styleClass;
    }

    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }

    public String getTheme() {
        return theme;
    }

    public void setTheme(String theme) {
        this.theme = theme;
    }

    public String getUrl() {
        return url;
    }

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

    public String getUrlType() {
        return urlType;
    }

    public void setUrlType(String urlType) {
        this.urlType = urlType;
    }

    public Pages(ValueStack arg0, HttpServletRequest request) {  
        super(arg0);  
        this.request = request;  
    }  
 
    @Override
    public boolean end(Writer writer,String body) {  
        boolean result = super.start(writer);  
        try {  
         //从ValueStack中取出数值  
            Object obj=this.getStack().findValue(pageNo);              
            pageNo = String.valueOf((Integer)obj);    
            obj=this.getStack().findValue(total);  
            total = String.valueOf((Integer)obj);   
 
            StringBuilder str = new StringBuilder();  
            Map cont= this.getStack().getContext();  
            StrutsRequestWrapper req=(StrutsRequestWrapper)cont.get(StrutsStatics.HTTP_REQUEST);  
               if(url==null||"".equals(url)){                
                url=(String)req.getAttribute("javax.servlet.forward.request_uri");
               }
               String pageNoStr="?pageNo=";
               if("dir".equals(urlType)){//当url的类型为目录类型时,比如http://localhost:8090/yongtree/page/1
                pageNoStr="";
                if("1".equals(pageNo)){//第一页时
                    if(url.lastIndexOf("/")!=url.length()-1){
                        if(url.lastIndexOf("1")==url.length()-1){//如果有页码1,则去掉1
                           url=url.substring(0, url.length()-1);
                        }else if(url.lastIndexOf("/")!=url.length()-1){//如果没有页码1,并且最后不是'/'时,加上'/'
                           url=url+"/";
                        }
                    }
                }else{
                        url=url.substring(0, url.lastIndexOf("/")+1);
                    }
               }
              
            
             //下面这段处理主要是用来处理动态查询的参数,并拼接成url
            StringBuffer perUrl=new StringBuffer("");
            if ( this.getParameters().size() != 0 ) {
                Iterator iter = this.getParameters().keySet().iterator();
                while (iter.hasNext()) {
                    String key = (String) iter.next();
                    Object o = this.getParameters().get(key);
                    perUrl.append("&").append(key).append("=").append(o);
                }
            }
            Integer cpageInt = Integer.valueOf(pageNo);  
            str.append("<span ");  
            if (styleClass != null) {  
                str.append(" class='"+styleClass+"'>");  
            } else {  
                str.append(">");  
            }  
              
            //文本样式  
            if (theme == null || "text".equals(theme)) {  
                //当前页与总页数相等  
                if (pageNo.equals(total)) {  
                    //如果total = 1,则无需分页,显示“[第1页] [共1页]”  
                    if ("1".equals(total)) {  
                        str.append("[第 " + pageNo + " 页]");  
                        str.append(" [共 " + total + " 页]");  
                    } else {  
                        //到达最后一页,显示“[首页] [上一页] [末页]”  
                        str.append("<a href='"+url+pageNoStr+"1"+perUrl+"'>[首页]</a> ");   
                        str.append("<a href='"+url+pageNoStr + (cpageInt - 1)+perUrl+"'>[上一页]</a>" );  
                        str.append(" <a href='"+url+pageNoStr + total+perUrl+"'>[末页]</a> ");  
                    }  
                } else {  
                    //当前页与总页数不相同  
                    if ("1".equals(pageNo)) {  
                        //第一页,显示“[首页] [下一页] [末页]”  
                        str.append("<a href='"+url+pageNoStr+"1"+perUrl+"'>[首页]</a>");  
                        str.append("<a href='"+url+pageNoStr + (cpageInt + 1) +perUrl+"'>[下一页]</a>");                         
                        str.append("<a href='"+url+pageNoStr + total +perUrl+"'>[末页]</a>");  
                    } else {  
                        //不是第一页,显示“[首页] [上一页] [下一页] [末页]”  
                        str.append("<a href='"+url+pageNoStr+"1"+perUrl+"'>[首页]</a>");  
                        str.append("<a href='"+url+pageNoStr + (cpageInt - 1)+perUrl+"'>[上一页]</a>");  
                        str.append("<a href='"+url+pageNoStr + (cpageInt + 1)+perUrl+"'>[下一页]</a>");  
                        str.append("<a href='"+url+pageNoStr + total +perUrl+"'>[末页]</a>");  
                    }  
                }  
            } else if ("number".equals(theme)) { //数字样式 [1 2 3 4 5 6 7 8 9 10 > >>]  
                Integer totalInt = Integer.valueOf(total);  
                 
                //如果只有一页,则无需分页  
                str.append("[ ");  
                if (totalInt == 1) {  
                    str.append("<strong>1</strong> ");  
                } else {                      
                    if (cpageInt > 1) {  
                        //当前不是第一组,要显示“<< <”  
                        //<<:返回前一组第一页  
                        //<:返回前一页  
                        str.append("<a href='"+url+pageNoStr+"1"+perUrl+"'><<</a> ");  
                        str.append("<a href='"+url+pageNoStr + (cpageInt - 1)+perUrl);  
                        str.append("'>‹</a> " );  
                    }else{                            
                        str.append("<< ‹ " );  
                    }  
                      
                    int v=(cpageInt-4)>0?(cpageInt-4):1;  
                    int v1=(cpageInt+4)<totalInt?(cpageInt+4):totalInt;  
                    if(v1==totalInt){  
                        v=totalInt-Util.pageNoQty;
                        v=(v<=0?1:v); //如果为负数,则修改为1
                    }else if(v==1&&v1<totalInt){  
                        v1=totalInt>Util.pageNoQty?Util.pageNoQty:totalInt;  
                    }  
                    //10个为一组显示  
                    for (int i = v; i <= v1; i++) {  
                        if (cpageInt == i) { //当前页要加粗显示  
                            str.append("<strong>"+i+"</strong> ");                                   
                        }else{  
                           //str.append("<a href='"+url + i +perUrl+"'>" + i + "</a> ");  
                            str.append("<a href='"+url+pageNoStr + i +perUrl+"'>" + i + "</a> ");  
                        }                              
                    }  
                    //如果多于1组并且不是最后一组,显示“> >>”  
                    if (cpageInt<totalInt) {  
                        //>>:返回下一组最后一页  
                        //>:返回下一页  
                        str.append("<a href='"+url+pageNoStr + (cpageInt + 1)+perUrl);  
                        str.append("'>›</a> " );  
                        str.append("<a href='"+url+pageNoStr + totalInt+perUrl);  
                        str.append("'>>></a> " );  
                    }else{  
                        str.append("› >> " );  
                   }  
                }  
                str.append("]");  
            }  
            str.append("</span>");  
              
            writer.write(str.toString());  
              
        } catch (IOException ex) {  
           ex.printStackTrace();
        }  
        return result;  
    }
 
}


PageAction.Java

package com.oaapp.tag;

import java.util.List;

import com.oaapp.util.Util;
import com.opensymphony.xwork2.ActionSupport;

public class PageAction  extends ActionSupport {
    public Integer pageNo=1;  

    public final Integer pageSize=Util.pageSize;

    public Integer total;
    
    public List<?> list;

    public Integer getPageNo() {
        return pageNo;
    }

    public void setPageNo(Integer pageNo) {
        this.pageNo = pageNo;
    }

    public Integer getTotal() {
        return total;
    }

    public void setTotal(Integer total) {
        this.total = total;
    }

    public List<?> getList() {
        return list;
    }

    public void setList(List<?> list) {
        this.list = list;
    }

    public Integer getPageSize() {
        return pageSize;
    }  
    
}


自定义分页标签结构的类: PageTag.java
 
/**
  * 自定义分页标签结构或属性
  * @date 2008 - 11 - 4 下午 03:00:40
  * @version 1.0
  */
publicclass  PageTag  extends  ComponentTagSupport {  
   
     private  String  pageNo ;  
     private  String  total ;  
     private  String  styleClass ;  
     private  String  theme ;
     private  String  url ;
     private  String  urlType ;
      
     publicvoid  setUrlType(String urlType) {
        this . urlType  = urlType;
    }
     publicvoid  setUrl(String url) {
        this . url  = url;
    }
     publicvoid  setTheme(String theme) {  
         this . theme  = theme;  
    }      
     publicvoid  setStyleClass(String styleClass) {  
         this . styleClass  = styleClass;  
    }  
     publicvoid  setPageNo(String pageNo) {  
         this . pageNo  = pageNo;  
    }  
     publicvoid  setTotal(String total) {  
         this . total  = total;  
    }  
 
  
     @Override  
     public  Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) {  
         returnnew  Pages(arg0, arg1);  
    }  
 
     protectedvoid  populateParams() {  
         super .populateParams();  
          
        Pages pages = (Pages) component ;  
        pages.setPageNo( pageNo );    
        pages.setTotal( total );  
        pages.setStyleClass( styleClass );  
        pages.setTheme( theme );  
        pages.setUrl( url );
        pages.setUrlType( urlType );
 
    }  
}  
 
创建自定义标签的tld文件:
<? xml  version = "1.0"  encoding = "UTF-8" ?>
<! DOCTYPE  taglib  PUBLIC  "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"  "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
< taglib >
     < tlib-version > 1.0 </ tlib-version >
     < jsp-version > 1.2 </ jsp-version >
     < short-name > yt </ short-name >
     < uri > /yongtree-tags </ uri >
     < display-name > "Java软件工程师,专注于java领域新技术的研究和系统设计。 的自定义标签 " </ display-name >
 
     < tag >
        < name > pages </ name >
        < tag-class > com.baiyyy.polabs.tag.PageTag </ tag-class >
        < body-content > jsp </ body-content >
        < description > 分页标签 </ description >
        < attribute >
            < name > pageNo </ name >
            < required > false </ required >
            < rtexprvalue > true </ rtexprvalue >
        </ attribute >
        < attribute >
            < name > total </ name >
            < required > false </ required >
            < rtexprvalue > true </ rtexprvalue >
        </ attribute >
        < attribute >
            < name > styleClass </ name >
            < required > false </ required >
            < rtexprvalue > true </ rtexprvalue >
            < description > 分页标签的样式 , 不配置此项将采用默认的样式 </ description >
        </ attribute >
        < attribute >
            < name > theme </ name >
            < required > false </ required >
            < rtexprvalue > true </ rtexprvalue >
            < description > 分页的主题,现支持 number|text 两种主题 </ description >
        </ attribute >
        < attribute >
            < name > url </ name >
            < required > false </ required >
            < rtexprvalue > true </ rtexprvalue >
            < description > 分页提交的路径,默认不用配置该项,自动获取系统访问路径。 </ description >
        </ attribute >
        < attribute >
            < name > urlType </ name >
            < required > false </ required >
            < rtexprvalue > true </ rtexprvalue >
            < description >
              url 的类型,现在支持两种 url 类型,第一种默认的 url ,这种情况不需要设置;第二种情况是目录型的 url ,比如 http://blog.csdn.net/yongtree ,此种情况请配置成 dir 。此种情况不支持动态查询,故标签体中不能加入参数
            </ description >
 
        </ attribute >
     </ tag >
</ taglib >
 
这样一个分页标签就实现完了,下一步让我们看看该怎样使用吧。
 
在页面中引入自定义的标签库:
<%@  taglib  prefix = "yt"  uri = "/yongtree-tags" %>  
 
开始配置分页标签信息:
< br >    
         < s:property  value = "total" /> < s:property  value = "pageNo" /> < br >< br >   
< yt:pages  pageNo = "pageNo"  total = "total"  styleClass = "page"  theme = "number" >
<!— 分页的动态查询参数需要全部注册在这里 à
     < s:param  name = "test1"  value = "test1" ></ s:param >
     < s:param  name = "test2"  value = "test2" ></ s:param >
     < s:param  name = "test3"  value = "test3" ></ s:param >
</ yt:pages >   
 
这样一个分页组件就完成了,但是只是完成了表现上的功能,我们还需要在后台进行封装,我对它进行了封装,做了一个 PageAction.java
publicclass  PageAction  extends  BaseAction {
     private  Integer  pageNo =1;  
     private  Integer  everyPage =10;
     private  Integer  total ;
    Page  page = new  Page();
     public  Integer getPageNo() {
        return pageNo ;
    }
     publicvoid  setPageNo(Integer pageNo) {
        this . page .setCurrentPage(pageNo);
        this . pageNo  = pageNo;
    }
     public  Integer getEveryPage() {
        return everyPage ;
    }
     publicvoid  setEveryPage(Integer everyPage) {
        this . everyPage  = everyPage;
    }
     public  Page getPage() {
        return page ;
    }
     publicvoid  setPage(Page page) {  
        this . page  = page;
    }
     public  Integer getTotal() {
        returnthis . page .getTotalPage();
    }
     publicvoid  setTotal(Integer total) {
        this . total  = total;
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值