STRUTS2自定义分页标签及过程中的问题

  1. 分页标签的开发   

   一直想写一个自己用的顺手的分页标签。网上的标签大部分都是在标签内部自成体系,不方便和页面上的查询条件结合在一起,即使有这样的标签,也不一定符合自己的实际需要。在这种需求的驱使下,决定写一个自己的分页标签,能够方便的和页面查询结合在一起,也能满足项目中的大部分需要。

       在参考网上其他人的自定义分页标签的基础上,加上自己的一些个性化需求,完成了自定义分页标签的编写。分页标签的样式如下:

       分页标签分为四部分:第一部分是记录数和总页数;第二部分是分页页码;第三部分是修改设置每页显示的记录数;第四部分是直接输入页码跳转。

STRUTS2下的自定义标签开发细节就不再复述,简单描述一下开发过程:

  • 第一步:建立一个WEB工程
  • 第二部:java部分的代码和普通WEB开发一样,路径在src目录的具体包中;
  • 第三部:tld文件放置在/WEB-INF/下。

通过上述步骤的完成后,就可以直接利用建立的工程进行测试标签是否正确。多的不说了,直接把代码贴出来:

PagerTag.java

/**
 * TODO
 * Struts2Pager.java
 * Administrator2012-12-18
 */
package com.citybug.tag;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

import com.opensymphony.xwork2.util.ValueStack;

/**
 * @author Administrator
 *
 */
public class PagerTag extends ComponentTagSupport {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String pageSize;
	private String pageNo;
	private String recordCount;
	private String pageCount;
	private String recordNum;
	private String showChangePageSize;
	private String showJumpPage;
	private String formId;

	public String getPageSize(){
		return pageSize;
	}
	
	public void setPageSize(String pageSize){
		this.pageSize=pageSize;
	}
	
	public String getPageNo(){
		return pageNo;
	}
	
	public void setPageNo(String pageNo){
		this.pageNo=pageNo;
	}
	
	public String getRecordCount(){
		return recordCount;
	}
	
	public void setRecordCount(String recordCount){
		this.recordCount=recordCount;
	}
	
	public String getPageCount(){
		return pageCount;
	}
	
	public void setPageCount(String pageCount){
		this.pageCount=pageCount;
	}

	public String getShowChangePageSize(){
		return showChangePageSize;
	}
	
	public void setShowChangePageSize(String showChangePageSize){
		this.showChangePageSize=showChangePageSize;
	}
	
	public String getShowJumpPage(){
		return showJumpPage;
	}
	
	public void setShowJumpPage(String showJumpPage){
		this.showJumpPage=showJumpPage;
	}
	
	public String getFormId(){
		return formId;
	}
	
	public void setFormId(String formId){
		this.formId=formId;
	}
	
	public String getRecordNum(){
		return recordNum;
	}
	
	public void setRecordNum(String recordNum){
		this.recordNum=recordNum;
	}
	
	@Override
	public Component getBean(ValueStack arg0, HttpServletRequest arg1,
			HttpServletResponse arg2) {
		return new Pager(arg0,arg1);
	}
	
	protected void populateParams(){
		super.populateParams();
		Pager pager=(Pager)component;
		pager.setPageNo(pageNo);
		pager.setPageSize(pageSize);
		pager.setRecordCount(recordCount);
		pager.setPageCount(pageCount);
		pager.setShowChangePageSize(showChangePageSize);
		pager.setShowJumpPage(showJumpPage);
		pager.setFormId(formId);
		pager.setRecordNum(recordNum);
	}
}

Pager.java

/**
 * TODO
 * Pager.java
 * Administrator2012-12-18
 */
package com.citybug.tag;

import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
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.opensymphony.xwork2.util.ValueStack;
/**
 * @author Administrator
 *
 */
public class Pager extends Component {
	private HttpServletRequest request;    
	private String pageNo;   //当前页码
	private String pageSize;	//每页记录数
    private String recordCount;   //总记录数
    private String pageCount;	  //总页数
    private String showChangePageSize;
    private String showJumpPage;
    private String formId;
    private String recordNum;
    
            
    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 getPageSize(){
    	return pageSize;
    }
    
    public void setPageSize(String pageSize){
    	this.pageSize=pageSize;
    }
    
    public String getRecordCount(){
    	return recordCount;
    }
    
    public void setRecordCount(String recordCount){
    	this.recordCount=recordCount;
    }
    
    public String setPageCount(){
    	return pageCount;
    }
    
    public void setPageCount(String pageCount){
    	this.pageCount=pageCount;
    }

    public Pager(ValueStack arg0, HttpServletRequest request) {  
        super(arg0);  
        this.request = request;  
    }
    
    public String getShowChangePageSize(){
    	return showChangePageSize;
    }
    
    public void setShowChangePageSize(String showChangePageSize){
    	this.showChangePageSize=showChangePageSize;
    }
    
    public String getShowJumpPage(){
    	return showJumpPage;
    }
    
    public void setShowJumpPage(String showJumpPage){
    	this.showJumpPage=showJumpPage;
    }
    
    public String getFormId(){
    	return formId;
    }
    
    public void setFormId(String formId){
    	this.formId=formId;
    }
    
    public String getRecordNum(){
    	return recordNum;
    }
    
    public void setRecordNum(String recordNum){
    	this.recordNum=recordNum;
    }
    
    @Override
    public boolean end(Writer writer,String body) {  
        boolean result = super.start(writer);  
        int iPageNo;
        int iRecordCount;
        int iPageCount;
        int iPageSize;
        boolean bShowChangePageSize;
        boolean bShowJumpPage;
        StringBuilder sb = new StringBuilder(); 
        try {  
        	//从ValueStack中取出数值  
            Object obj=this.getStack().findValue(pageNo);              
            pageNo = String.valueOf((Integer)obj);    
            obj=this.getStack().findValue(recordCount);  
            recordCount = String.valueOf((Integer)obj);   
            
            obj=this.getStack().findValue(pageSize);
            pageSize=String.valueOf((Integer)obj);
            obj=this.getStack().findValue(showChangePageSize);
            bShowChangePageSize=Boolean.valueOf(String.valueOf(obj));
            obj=this.getStack().findValue(recordNum);
            recordNum=String.valueOf((Integer)obj);
            obj=this.getStack().findValue(showJumpPage);
            bShowJumpPage=Boolean.valueOf(String.valueOf(obj));
            
            iPageSize=Integer.valueOf(pageSize);
            iPageNo=Integer.valueOf(pageNo);
            iRecordCount=Integer.valueOf(recordCount);
            iPageCount=(iRecordCount+iPageSize-1)/iPageSize;
            sb.append("<style type=\"text/css\">");  
            sb.append(".pagination {padding: 5px;float:right;font-size:10px;}");  
            sb.append(".pagination a, .pagination a:link, .pagination a:visited {padding:2px 5px;margin:2px;border:1px solid #aaaadd;text-decoration:none;color:#006699;}");  
            sb.append(".pagination a:hover, .pagination a:active {border: 1px solid #ff0000;color: #000;text-decoration: none;}");  
            sb.append(".pagination span.current {padding: 2px 5px;margin: 2px;border: 1px solid #ff0000;font-weight: bold;background-color: #ff0000;color: #FFF;}");  
            sb.append(".pagination span.disabled {padding: 2px 5px;margin: 2px;border: 1px solid #eee; color: #ddd;}");  
            sb.append("</style>\r\n");  
            sb.append("<div class=\"pagination\">\r\n");  
            if(iRecordCount == 0){  
                sb.append("<strong>没有可显示的项目</strong>\r\n");  
            }else{  
                //页号越界处理  	
                if(iPageNo > iPageCount){      iPageNo = iPageCount; }  
                if(iPageNo < 1){      iPageNo = 1; }    
          
                // 把当前页号设置成请求参数  
                sb.append("<input type=\"hidden\" name=\"").append("pageNo")  
                    .append("\" value=\"").append(pageNo).append("\"/>\r\n");  
                  
                // 输出统计数据  
                sb.append("共 <strong>").append(recordCount)  
                    .append("</strong> 项")  
                    .append(", 共 <strong>")  
                    .append(iPageCount)  
                    .append("</strong> 页: \r\n");  
                  
                //上一页处理  
                if (iPageNo == 1) {  
                    sb.append("<span class=\"disabled\">« 上一页")  
                        .append("</span>\r\n");  
                } else {  
                    sb.append("<a href=\"javascript:turnOverPage(")  
                      .append((iPageNo - 1))  
                      .append(")\">« 上一页</a>\r\n");  
                }  
                  
                //如果前面页数过多,显示"..."  
                int start = 1;   
                if(iPageNo > 4){  
                    start = iPageNo - 1;  
                    sb.append("<a href=\"javascript:turnOverPage(1)\">1</a>\r\n") 
                    	.append("<a href=\"javascript:turnOverPage(2)\">2</a>\r\n")  
                    	.append("…\r\n");  
                }  
	            //显示当前页附近的页  
	            int end = iPageNo + 1;  
	            if(end > iPageCount){  
	                end = iPageCount;  
	            }  
	            for(int i = start; i <= end; i++){  
	                if(iPageNo == i){   //当前页号不需要超链接  
	                    sb.append("<span class=\"current\">")  
	                        .append(i)  
	                        .append("</span>\r\n");  
	                }else{  
	                    sb.append("<a href=\"javascript:turnOverPage(")  
	                        .append(i)  
	                        .append(")\">")  
	                        .append(i)  
	                        .append("</a>\r\n");  
	                }  
	            }  
	            //如果后面页数过多,显示"..."  
	            if(end < iPageCount - 2){  
	                sb.append("…\r\n");  
	            }  
	            if(end < iPageCount - 1){  
	                sb.append("<a href=\"javascript:turnOverPage(")  
	                .append(iPageCount - 1)  
	                .append(")\">")  
	                .append(iPageCount - 1)  
	                .append("</a>\r\n");  
	            }  
	            if(end < iPageCount){  
	                sb.append("<a href=\"javascript:turnOverPage(")  
	                .append(iPageCount)  
	                .append(")\">")  
	                .append(iPageCount)  
	                .append("</a>\r\n");   
	            }  
    	              
	            //下一页处理  
	            if (iPageNo == iPageCount) {  
	                sb.append("<span class=\"disabled\">下一页 »")  
	                    .append("</span>\r\n");  
	            } else {  
	                sb.append("<a href=\"javascript:turnOverPage(")  
	                    .append((iPageNo + 1))  
	                    .append(")\">下一页 »</a>\r\n");  
	            } 
    	            
	            if(bShowChangePageSize){
	            	//每页记录数
	            	sb.append("每页记录数:<select id=\"recordNum\" name=\"recordNum\" onChange=\"turnOverPage(" + pageNo + ")\">");
            		if(recordNum.equals("20")){
            			sb.append("<option value=\"20\" selected>20</option>");
            		}else{
            			sb.append("<option value=\"20\">20</option>");
            		}
            		if(recordNum.equals("50")){
            			sb.append("<option value=\"50\" selected>50</option>");
            		}else{
            			sb.append("<option value=\"50\">50</option>");
            		}
            		if(recordNum.equals("100")){
            			sb.append("<option value=\"100\" selected>100</option>");
            		}else{
            			sb.append("<option value=\"100\">100</option>");
            		}
            		if(recordNum.equals("150")){
            			sb.append("<option value=\"150\" selected>150</option>");
            		}else{
            			sb.append("<option value=\"150\">150</option>");
            		}
            		if(recordNum.equals("200")){
            			sb.append("<option value=\"200\" selected>200</option>");
            		}else{
            			sb.append("<option value=\"200\">200</option>");
            		}
            		sb.append("</select>");
	            }
    	            
	            if(bShowJumpPage){
	            	//跳转页
	            	sb.append(" 跳转到<input id=\"pageNum\" type=\"text\" name=\"pageNum\" size=\"2\" length=\"5\" ")
	            		.append("onKeyPress=\"inputInt(event)\" ")
	            		.append(">")
	            		.append("<a href=\"javascript:jumpPage();")  
	            		.append("\">跳转 »</a>\r\n"); 
	            } 
    	            
	            // 生成提交表单的JS  
	            sb.append("<script language=\"javascript\">\r\n")  
	            	.append("  function turnOverPage(no){\r\n")
	            	.append("    if(no>").append(iPageCount).append("){")  
	            	.append("      no=").append(iPageCount).append(";}\r\n")  
	            	.append("    if(no<1){no=1;}\r\n")
	            	.append("    document.getElementById('" + formId + "').pageNo.value=no;\r\n")  
	            	.append("    document.getElementById('" + formId + "').submit();\r\n")
	            	.append("  }\r\n")
	            	.append(" function inputInt(event){\r\n")
	            	.append("  var keyNum;\r\n")
	            	.append("  var keyCode;\r\n")
	            	.append("  if(window.event){\r\n")
	            	.append("      keyNum=event.keyCode;\r\n")
	            	.append("  }else if(event.which){\r\n")
	            	.append("      keyNum=event.which;\r\n")
	            	.append("  }\r\n")
	            	.append("  if(keyNum<46 || keyNum>57){\r\n")
	            	.append("    if(window.event){\r\n")
	            	.append("       event.returnValue=false;\r\n")
	            	.append("    }else{\r\n")
	            	.append("       event.preventDefault();\r\n")
	            	.append("    }\r\n")
	            	.append("   }\r\n")
	            	.append("	}\r\n")
	            	.append("  function jumpPage(){\r\n")
	            	.append("    var no=1;\r\n")
	            	.append("    if(document.getElementsById('pageNum').value==''){\r\n")
	            	.append("      alert('跳转页码必须填写!');\r\n")
	            	.append("    }else{\r\n")
	            	.append("      no=parseInt(document.getElementsById('pageNum').value);\r\n")
	            	.append("    }\r\n")
	            	.append("    turnOverPage(no);\r\n")
	            	.append("  }\r\n")
	            	.append("</script>\r\n");  
	        }  
    	    sb.append("</div>\r\n");  
              
            writer.write(sb.toString());  
              
        } catch (IOException ex) {  
           ex.printStackTrace();
        }  
        return result;  
    }
}

Pager.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>cb</short-name>
    <uri>/citybug-tags</uri>
    <display-name>"自定义分页标签"</display-name>
 
    <tag>
       <name>pager</name>
       <tag-class>com.citybug.tag.PagerTag</tag-class>
       <body-content>jsp</body-content>
       <description>分页标签</description>
       <attribute>
           <name>pageNo</name>
           <required>false</required>
           <rtexprvalue>true</rtexprvalue>
       </attribute>
       <attribute>
           <name>recordCount</name>
           <required>false</required>
           <rtexprvalue>true</rtexprvalue>
       </attribute>
       <attribute>
           <name>pageSize</name>
           <required>false</required>
           <rtexprvalue>true</rtexprvalue>
       </attribute>
       <attribute>
           <name>showChangePageSize</name>
           <required>false</required>
           <rtexprvalue>true</rtexprvalue>
       </attribute>
       <attribute>
           <name>showJumpPage</name>
           <required>false</required>
           <rtexprvalue>true</rtexprvalue>
       </attribute>
       <attribute>
           <name>formId</name>
           <required>false</required>
           <rtexprvalue>true</rtexprvalue>
       </attribute>
    </tag>
</taglib>

2.自定义标签的打包

自定义标签经过测试没有问题后,就要打包成JAR文件用到项目中去了,如何打包呢?方法比较简单:

  • 建立一个空目录
  • 到部署服务器下,把组成标签的java的class类复制到建立的目录中,当然,要保持class类的路径和tld中的类路径一致
  • 把部署服务器下的“META_INF”复制到建立的目录中
  • 把tld文件复制到META_INF目录中
  • 选中目录中的全部文件,使用winrar压缩软件,把选中的文件制作成压缩包。压缩格式选择为“ZIP”,如果是“RAR”格式,项目运行时,会出现“打不开文件”的错误信息。然后将要锁文件后缀改为JAR即可。
  • 把新建的JAR文件复制到项目的LIB目录下,就可以使用了。
3. 页面上如何使用

页面上使用和struts2自己的标签没有什么区别:

在页面的开头引用标签:

<%@ taglib prefix="cb"  uri="/citybug-tags" %>

这个自定义标签由于要达到和查询条件融合在一起,所以需要把标签和查询条件放置在同一个form中。

<cb:pager pageNo="page.pageNo" pageSize="page.pageSize" formId="form1" recordCount="page.recordCount" showChangePageSize="true" showJumpPage="true"/>
在上面的标签使用中,有page对象,这就是action中用于返回分页信息的对象。这个对象的代码非常简单,仅仅包含三个属性和这三个属性的getter和setter方法。代码如下:

Page.java

/**
 * TODO
 * Page.java
 * Administrator2012-12-20
 */
package com.citybug.comm;

/**
 * @author Administrator
 *
 */
public class Page {
	private int pageNo;
	private int pageSize;
	private int recordCount;
	
	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 getRecordCount(){
		return recordCount;
	}
	
	public void setRecordCount(int recordCount){
		this.recordCount=recordCount;
	}
}

那么在action中,需要一个通用方法,把page中的各个参数之间的逻辑关系表述清楚,我的代码如下:

private Page setPagePro(int recordCount){
		Page page=null;
		int pageCount;
		int iPageNum;
		try{
			pageNo=this.getPageNo();
			pageSize=this.getPageSize();
			recordNum=this.getRecordNum();
			pageNum=this.getPageNum();
			
			if(pageSize==0){
				pageSize=20;
			}
			if(pageNo==0){
				pageNo=1;
			}
			if(recordNum!=0){
				if(pageSize!=recordNum){
					pageSize=recordNum;
				}
			}
			if(pageNum!=null && !pageNum.equals("")){
				iPageNum=Integer.valueOf(pageNum);
				if(iPageNum>0){
					if(pageNo!=iPageNum){
						pageNo=iPageNum;
					}
				}
			}
			
			pageCount=(recordCount+pageSize-1)/pageSize;
			if(pageNo>pageCount){
				pageNo=pageCount;
			}
			page=new Page();
			page.setPageNo(pageNo);
			page.setPageSize(pageSize);
			page.setRecordCount(recordCount);
		}catch(Exception ex){
			ex.printStackTrace();
		}
		
		return page;
	}

为什么上面要这么写,是因为标签中可以改变每页的记录数和页码的跳转,每页记录数是以默认值为准,还是以页面上“每页记录数”下拉框中选择的数量为准?是以默认的页码为准还是以跳转中输入的页码为准?就是上面这个过程要解决的问题。其中的逻辑并不复杂。

那么接下来,只要把记录list和page对象返回给jsp页面,分页就成功了!

4。分页标签开发中的几个注意事项:
  • list如何传入标签?

            在我们开发自定义标签时,可能会碰到要把一个list对象传给标签,然后由标签进行处理后,给出一个结果。但是struts2中却是把所有的参数认为是String。那么就会出现在自定义标签的java中要获得list对象时,就不知道如何才能获得这个list。在参照struts2的core中源码情况下,有了下面的解决办法:

           在继承自“ComponentTagSupport”的类中,把list的变量类型设置为Object。

private Object list;

           在继承自“Component”的类中,在方法“end(Writer writer,String body)”中获取list的对象时,用下面的语句进行转换:

          

obj=this.getStack().findValue((String)list);    
ArrayList<?> beanList = (ArrayList<?>)obj;

 这样,就可以获得list的队列内容。至于如何使用,可以使用反射,也可以对队列进行类型转换等等,这就要看具体的需要了。

  • 在标签中,传入的是字符串或者具体的值,而不是变量时,如何获取到值?

看完上面的自定义标签,在end过程中,看到取值使用的是 Object obj=this.getStack().findValue(pageNo); 的方法。那么就会形成一种思维定势,认为获取标签传入的值都是采用这样的方式获取值。但是并不是如此,这是因为JSP页面上是这么写的   pageNo=”page.pageNo".那么,如果是直接写成 pageNo=“1”,就不用再使用findValue这个方法了,而是直接使用pageNo变量即可。这本不是个问题,只是在此给提个醒.

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Struts2 和 Hibernate 是两个非常流行的 Java Web 开发框架,它们可以很好地协同工作。下面是 Struts2 和 Hibernate 整合的基本步骤: 1. 引入相关依赖 在项目的 pom.xml 文件添加 Struts2 和 Hibernate 相关依赖。例如: ``` <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>${struts.version}</version> </dependency> ``` 2. 配置数据库连接 在项目的配置文件配置数据库连接。例如,在 Hibernate ,可以在 hibernate.cfg.xml 文件指定数据库连接信息。同时,还需要在该文件定义 Hibernate 的实体类映射信息。 3. 配置 Hibernate 的 SessionFactory 在 Spring ,可以使用 LocalSessionFactoryBean 配置 Hibernate 的 SessionFactory。在配置文件定义该 bean,并将数据库连接和实体类映射信息注入到该 bean 。 4. 配置事务管理器 在 Spring ,可以使用 HibernateTransactionManager 来管理 Hibernate 的事务。在配置文件定义该 bean,并将 SessionFactory 注入到该 bean 。 5. 配置 Struts2 的 Action 在 Struts2 ,可以使用 Hibernate 的 SessionFactory 来进行数据库操作。在 Action ,通过注入 SessionFactory 来获得 Hibernate 的 Session 对象,从而进行数据库操作。 以上是 Struts2 和 Hibernate 整合的基本步骤,具体实现还需要根据项目的实际情况进行调整和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值