struts2分页

本文介绍了一种基于Struts2框架的自定义分页组件实现方案,包括Action配置、JSP页面展示及PageBean处理流程等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一直都在做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上的分页效果,效果如下:

[img]http://dl.iteye.com/upload/attachment/206169/7339f642-79ba-3927-b959-48224f74a0c5.jpg[/img]

当然要达到上面的效果,还得需要个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包如下:
[img]http://dl.iteye.com/upload/attachment/236559/8ef62412-eddc-319e-9126-7542eca575b2.jpg[/img]

源码见附件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值