`

struts2分页

阅读更多
一直都在做web,一直都在搞分页,一直没发现好的分页组件,用过displaytag,也用过jmesa,但是都不能让自己满意,虽然本人原来一直不喜欢struts2,但是工作需要,也顾不了那么多了,但是struts2本身并没有对分页提供什么帮助,看来一切都还得从头开始。首先要做的就是在网上查资料,但是并没有发现自己满意的分页方式,于是找了一个离自己要求差距不是很大的一个例子,在此基础之上进行了改装,最后基本达到了自己想要的效果。下面对此进行简单的介绍:

环境:

JDK1.6
tomcat6
eclipse3.5
struts2.1.8.1

要实现分页,基本流程为JSP->PageTag->PageBean->Action,当然也可以反过来说。
1. 首先从Action说起吧,Action需要几个参数,其中pageNo(当前页),total(总共多少条记录)是必需的,查询的条件参数则是可选的。基本的Action代码如下:

public class HelloWorld extends ActionSupport {

	private static final long serialVersionUID = 7046981255032101657L;

	// 总共页数
	private int total = 40;
	// 默认当前页为第一页
	private int pageNo = 1;
	// 下面为条件参数
	private String test = "test";
	private long test1 = 5L;
	private float test2 = 9.8F;
	private int test3 = 8;

	public String execute() {
		return SUCCESS;
	}

	public int getTotal() {
		return total;
	}

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

	public int getPageNo() {
		return pageNo;
	}

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

	public String getTest() {
		return test;
	}

	public void setTest(String test) {
		this.test = test;
	}

	public long getTest1() {
		return test1;
	}

	public void setTest1(long test1) {
		this.test1 = test1;
	}

	public float getTest2() {
		return test2;
	}

	public void setTest2(float test2) {
		this.test2 = test2;
	}

	public int getTest3() {
		return test3;
	}

	public void setTest3(int test3) {
		this.test3 = test3;
	}

}


需要说明的,上面的一些参数如pageNo,total对于每个需要分页的Action来说都是固定的,所以可以提取到一个抽象的类中。只要JSP页面的参数名与Action的变量名对应起来,ONGL就会把相应的值附给这些变量。如下:

<p:pages pageNo="pageNo" total="total"
			includes="test,test1,test2,test3"/>


其中includes包含的就是查询的条件参数名,它们与Action查询变量相对应。通过上面的JSP页面,可以看出用到了一个tag,不过这个tag tld文件很简单,page.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>2.2.3</tlib-version>     
    <jsp-version>1.2</jsp-version>     
    <short-name>p</short-name>     
    <uri>/p</uri>     
    <display-name>"pages Tags"</display-name>     
          
        <tag>     
            <name>pages</name>     
            <tag-class>com.page.PageTag</tag-class>      
            <body-content>empty</body-content>     
            <attribute>      
                <name>pageNo</name>     
                <required>true</required>     
                <rtexprvalue>true</rtexprvalue>     
            </attribute>     
            <attribute>     
                <name>total</name>     
                <required>true</required>     
                <rtexprvalue>true</rtexprvalue>     
            </attribute>
            <attribute>     
                <name>includes</name>     
                <required>false</required>     
                <rtexprvalue>true</rtexprvalue>     
            </attribute>
        </tag>     
</taglib>


这个tag对应的tag类也很简单:

public class PageTag extends ComponentTagSupport {
	
	private static final long serialVersionUID = 7242423813230124088L;
	//这里传递的参数需要用字符串的形式
	private String pageNo;
	private String total;
	private String includes;

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

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

	public String getIncludes() {
		return includes;
	}

	public void setIncludes(String includes) {
		this.includes = includes;
	}

	@Override
	public Component getBean(ValueStack arg0, HttpServletRequest arg1,
			HttpServletResponse arg2) {
		return new Pages(arg0);
	}

	protected void populateParams() {
		super.populateParams();

		Pages pages = (Pages) component;
		pages.setPageNo(pageNo);
		pages.setIncludes(includes);
		pages.setTotal(total);

	}
}


需要注意的是ongl对变量的获取方法findValue的形式并不多,只提供对String的支持,因此需要用字符串变量,这方面的确不是很完善。这个tag会把相应的值交给PageBean进行分页显示的处理。因此最重要的东西其实是PageBean类:

public class Pages extends Component {

	private String pageNo;
	private String total;
	private String includes;

	public String getIncludes() {
		return includes;
	}

	public void setIncludes(String includes) {
		this.includes = includes;
	}

	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 Pages(ValueStack arg0) {
		super(arg0);
	}

	@Override
	public boolean start(Writer writer) {

		boolean result = super.start(writer);
		StringBuilder str = new StringBuilder();
		Map<String, Object> cont = stack.getContext();
		StrutsRequestWrapper req = (StrutsRequestWrapper) cont
				.get(StrutsStatics.HTTP_REQUEST);

		String url = (String) req
				.getAttribute("javax.servlet.forward.request_uri");

		// 从ValueStack中取出数值
		Object obj = stack.findValue(pageNo);
		pageNo = String.valueOf(obj);
		obj = stack.findValue(total);
		total = String.valueOf(obj);

		StringBuilder perUrl = new StringBuilder("");
		if (includes != null && includes.trim().length() > 0) {
			String[] perm = includes.split(",");
			for (int i = 0; i < perm.length; i++) {
				String permName = perm[i];
				Object obje = stack.findValue(permName);

				perUrl.append("&");
				perUrl.append(permName);
				perUrl.append("=");
				perUrl.append(obje);
			}
		}

		//用于计算的当前页整数形式
		int cpageInt = Integer.valueOf(pageNo);
		str.append("<div class='pagination'>");
		Integer totalInt = Integer.valueOf(total);

		// 如果只有一页,则无需分页

		if (totalInt == 1) {
			str.append("<span class='current'>1</span> ");
		} else {

			// 显示上一页与第一页
			if (cpageInt == 1) {
				str.append("<span class='disabled'><< 上一页</span>");
				str.append("<span class='current'>1</span>");
			} else {
				str.append("<a href='");
				str.append(url);
				str.append("?pageNo=");
				str.append(cpageInt - 1);
				str.append(perUrl);
				str.append("'>« 上一页</a>");
				
				str.append("<a href='");
				str.append(url);
				str.append("?pageNo=1");
				str.append(perUrl);
				str.append("'>1</a>");
			}

			// 当前页超过5时第一页后面加点,因为中间相隔了第二页
			if (cpageInt - 4 > 1)
				str.append("<span class='gap'>...</span>");

			// v,v1分别代表中间页数的最小值和最大值,3表示显示当前页的前后三页
			int v = (cpageInt - 3) > 1 ? (cpageInt - 3) : 2;
			int v1 = (cpageInt + 3) < totalInt ? (cpageInt + 3) : totalInt - 1;
			if (v1 == totalInt) {
				v = totalInt - 10;
			} else if (v == 1 && v1 < totalInt) {
				v1 = totalInt > 10 ? 10 : totalInt;
			}

			// 
			for (int i = v; i <= v1; i++) {
				if (cpageInt == i) { // 当前页要加粗显示
					
					str.append("<span class='current'>");
					str.append(i);
					str.append("</span>");
				} else {
					str.append("<a href='");
					str.append(url);
					str.append("?pageNo=");
					str.append(i);
					str.append(perUrl);
					str.append("'>");
					str.append(i);
					str.append("</a>");
				}
			}

			if (cpageInt < totalInt - 4)
				str.append("<span class='gap'>...</span>");
			// 显示最后一页
                        if (cpageInt == totalInt) { // 当前页要加粗显示
				
				str.append("<span class='current'>");
				str.append(totalInt);
				str.append("</span>");
			} else{
				str.append("<a href='");
				str.append(url);
				str.append("?pageNo=");
				str.append(totalInt);
				str.append(perUrl);
				str.append("'>");
				str.append(totalInt);
				str.append("</a>");
			}
			
			if (cpageInt == totalInt) {
				str.append("<span class='disabled'>下一页 >></span>");
			} else {
				str.append("<a href='");
				str.append(url);
				str.append("?pageNo=");
				str.append(cpageInt + 1);
				str.append(perUrl);
				str.append("'>下一页 >></a>");
			}
		}

		str.append("</div>");

		try {
			writer.write(str.toString());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return result;
	}
}

不得不说,这个类还的确花了本人不少时间,不过总算把它做完善了,实现的效果类似JE上的分页效果,效果如下:



当然要达到上面的效果,还得需要个CSS才行,这里其实就是把JE的CSS拿来用了:

.pagination {
    padding: 5px;
    float: right;
}

.pagination a, .pagination a:link, .pagination a:visited {
    padding: 2px 5px 2px 5px;
    margin: 2px;
    border: 1px solid #aaaadd;
    text-decoration: none;
    color: #006699;
}

.pagination a:hover, .pagination a:active {
    border: 1px solid #006699;
    color: #000;
    text-decoration: none;
}

.pagination span.current {
    padding: 2px 5px 2px 5px;
    margin: 2px;
    border: 1px solid #006699;
    font-weight: bold;
    background-color: #006699;
    color: #FFF;
}


因此最后需要注意的一点就是在JSP页面引入相应的的CSS与TLD文件。如:

<%@ taglib prefix="p" uri="/WEB-INF/page.tld"%>
<html>
<link href="./css.css" media="screen" rel="stylesheet" type="text/css" />


这样,一个还算完善的分页就做完了,虽然这些东西经常做来发现没什么意思,但是又不得不做,所以还不如一次性做它做彻底,以后也就不需要再为此事操心了。

jar包如下:


源码见附件。
  • 大小: 6 KB
  • 大小: 11.6 KB
分享到:
评论
15 楼 wyj983759591 2013-12-19  
String url = (String) req.getAttribute("javax.servlet.forward.request_uri");

这一段,自画面刷新,跳到XX页,能正确取值
但是,别的画面返回来的时候,取得时前画面的Action,再分页就乱套了
比如,分页画面 ,按下【更新按钮】,到更新画面,更新完成自动返回来,再点分页按钮,就跑到更新画面去了!没法分页!
14 楼 clyhpove 2013-11-11  
“需要说明的,上面的一些参数如pageNo,total对于每个需要分页的Action来说都是固定的,所以可以提取到一个抽象的类中。”
但是每个Action都已经继承了一个类了么,难道java里面可以同时继承多个了?
13 楼 leesenone 2011-08-19  
代码分享下。375710128@qq.com。谢谢
12 楼 261667318 2010-10-03  
楼主我还有点不懂。这个分页标签要查询的表名在哪里呢,还有比如一张表里查询某些字段是不是就是标签里的<includes>啊
11 楼 hiyoku 2010-06-02  
test test1。。。是传参的
10 楼 hiyoku 2010-06-02  
封装的很好,轻量级的,很好用
9 楼 seven1987 2010-05-18  
那几个test test是干嘛的啊???
8 楼 seven1987 2010-05-11  
在哪里控制每页显示记录的条数呢?
7 楼 fansofjava 2010-04-13  
就把上面的代码复制下去就能运行,只是需要加几个struts2的JAR包。
6 楼 yanxunjian 2010-04-13  
struts2分页有实例源码吗?传上来分享下吧 哥哥
5 楼 yanxunjian 2010-04-13  
有没有源码实例呢?上传来分享一下可以吗?
4 楼 fansofjava 2010-03-30  
这个很容易理解,底层写两个方法,一个方法用于获取要显示的记录,一个用于获取总共多少条记录,照上面的方法,可以在Action获得当前的页号pageNo,至于每页显示多少条记录,可以自己设定,根据页号pageNo与自定义的页面pageSize大小,就可以得到下页将要显示的数据了。
3 楼 tinguo002 2010-03-30  
打错字了,上面的一句:  还是不明白数据集是什么时候被分割的555
2 楼 tinguo002 2010-03-30  
55555555555555
我一直都是认为,在查询数据库的时候就已经把返回的List进行分割了,我最难以理解的是如何在service中把分割的参数同DAO一起用,可是在想struts2中好像都不是这样子的哦哦,在这里也没有看到咯  
不是不明白数据集是什么时候被分割的55555
哥哥有看到回我一下哦
1 楼 tinguo002 2010-03-30  
哇是呀 
我最近也在为struts2的分页发愁,所以去网上查了一下,发现关于分页的帖子非常多,而且关注的人也非常多耶
楼主的贴子已经是我查了好几天下来最优的一个了。
我慢慢啃。
楼主说对struts2特不喜欢呀,不知道有啥原因咯,呵呵我觉得很好用呀 哈哈

相关推荐

    struts2增删改查,struts2分页查询

    在探讨Struts2框架下的增删改查以及分页查询功能时,我们首先需要理解Struts2框架本身。Struts2是Apache软件基金会的一个开源Web应用框架,它继承了Struts1的一些特性,并在此基础上进行了大量的改进和扩展,提供了...

    Struts2分页源码技术的应用

    Struts2分页源码技术是Web开发中一个重要的实践,尤其是在处理大数据量时,能够有效地提高用户体验,避免一次性加载过多数据导致页面响应慢。在本文中,我们将深入探讨Struts2分页技术的实现原理、应用方法以及与...

    经典struts2分页方法 JAVA_WEB必备分页 源码

    经典Struts2分页方法是Java Web开发者需要掌握的核心技能之一。 分页的实现通常涉及到以下几个关键知识点: 1. **Action类**:在Struts2中,Action类是处理用户请求的中心。为了实现分页,我们需要创建一个包含...

    Struts2分页

    Struts2实现分页功能,代码完整简洁易懂,可以直接拿去使用,欢迎拍砖

    struts2分页显示

    该文档详细描述了struts2版本的分页显示,值得一读

    hibernate+struts2分页代码

    【hibernate+struts2分页代码】是关于如何在Java Web开发中结合Hibernate ORM框架和Struts2 MVC框架实现数据分页的功能。在Web应用程序中,分页是提高用户体验的重要手段,它允许用户逐步浏览大量数据,而无需一次性...

    struts2分页效果第二种

    本文将详细介绍Struts2实现分页效果的第二种方法。 在Struts2中,实现分页通常涉及以下几个关键步骤: 1. **模型(Model)**:首先,我们需要一个实体类来存储待分页的数据,例如`User`。然后,创建一个`PageBean`类...

    Struts2分页(含mysql)

    Struts2分页技术是Java Web开发中一种常见的数据展示方式,它允许用户在大量数据中按需加载和浏览信息,提升用户体验。本教程将详细讲解如何在Struts2框架中实现分页功能,并结合MySQL数据库进行数据操作。 首先,...

    MyBatis+struts2分页

    MyBatis增 删 改 查 struts2分页

    Struts2分页-自定义标签-类似百度分页

    Struts2分页是Web开发中的一个重要概念,它主要用于处理大量数据时,避免一次性加载所有数据导致页面响应慢或者浏览器崩溃。在这个场景中,我们提到的是使用自定义标签实现类似于百度分页的效果,这是一种常见的用户...

    Struts2分页方法

    ### Struts2分页方法详解 #### 知识点一:Struts2框架与分页概念 Struts2是Apache软件基金会的一个开源Web应用框架,它继承了Struts1的优点并改进了许多不足之处,提供了更丰富的插件和标签库,支持拦截器、结果...

    JSP Struts2 分页 导出Excel

    **JSP Struts2 分页 导出Excel** 在Web开发中,经常需要处理大量数据,这时分页显示和导出功能就显得尤为重要。JSP(JavaServer Pages)和Struts2作为Java Web开发中的常见技术,可以帮助我们构建动态、交互的网页...

    Struts2自定义分页标签

    本资源详细介绍了如何在Struts2中自定义分页标签,使得开发过程更加便捷。 在Struts2中,分页通常涉及到以下几个关键步骤: 1. **创建Action类**:首先,你需要创建一个Action类,该类将处理用户的请求,包括获取...

    Struts2分页程序

    根据提供的信息,我们可以深入探讨如何在Struts2框架中实现分页功能。Struts2是一个开源的、用于创建企业级Java Web应用的框架。它基于MVC(模型-视图-控制器)架构模式,能够帮助开发者高效地组织代码并简化Web开发...

    struts2 分页

    struts2 分页struts2 分页struts2 分页struts2 分页struts2 分页struts2 分页struts2 分页struts2 分页struts2 分页struts2 分页struts2 分页 直接导入jar包就可以了。

    struts2分页系统

    这是struts的一个练习 这是struts的一个练习这是struts的一个练习这是struts的一个练习

    实用的struts2分页

    ### 实用的Struts2分页技术解析与实践 #### 引言 在Web开发中,数据展示往往需要进行分页处理,以提高用户体验和服务器性能。Struts2框架提供了强大的MVC架构支持,其中分页功能是其常用且实用的一部分。本文将深入...

    struts2分页更容易简单很快学会

    Struts2 分页技术是Java Web开发中常用的一种方法,用于在大量数据列表中实现高效、用户友好的浏览体验。本篇文章将详细讲解如何在Struts2框架中结合Hibernate ORM库实现分页功能。 首先,我们需要理解分页的基本...

    struts2分页模型

    Struts2分页模型是Java Web开发中一种常见的技术,用于在用户界面展示大量数据时进行数据的组织和浏览。分页的主要目的是提高用户体验,避免一次性加载过多数据导致页面响应变慢或者内存压力过大。本篇文章将深入...

Global site tag (gtag.js) - Google Analytics