曾经拜读过很多的关于分页处理的文章,但是有关Struts分页处理的却少之又少,所幸自己写了一个,希望能给朋友们有所帮助J
首先介绍一下整个流程:
第一步:因为需要从数据库中取出查询的结果并显示在网页上,所以必须先写一个查询数据库的类,
我们把它命名为Article.java,里面有一个query()方法,用它来处理查询,代码如下:
package com.swsoftware.beans
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.swsoftware.hljhz.admin.forms.ArticleForm;//Struts中的form类,此处是有关Article的form
import com.swsoftware.core.db.DBUtils;//此外引用的类DBUtils中无非是一些连接数据库
//用的代码,所以不做介绍了
public class Article{
protected Log log = LogFactory.getLog(this.getClass());
private ArticleForm articleform = null;
public List query(String where) throws SQLException {
List list = new ArrayList();
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
StringBuffer buf = new StringBuffer();
buf.append("select * from Article order by articleID desc ");
try {
connection = DBUtils.getConnection();//DBUtils中的方法,取得连接用
statement = connection.prepareStatement(buf.toString());
rs = statement.executeQuery();
while (rs.next()) {
articleform = new ArticleForm();
articleform.setArticleID(rs.getInt("articleID"));
articleform.setContent(rs.getString("content"));
articleform.setTitle(rs.getString("title"));
list.add(articleform);
}
return list;
} catch (SQLException sqle) {
log.error("Sql Execution Error!", sqle);
throw new SQLException("Error Executing SQL in "
+ this.getClass().getName());
} finally {
DBUtils.close(rs, statement, connection);// DBUtils中的方法,用以关闭连接
}
}
}
第二步:由于前面引用了ArticleForm,所以这里给出了ArticleForm的代码:
package com.swsoftware.forms
import org.apache.struts.validator.ValidatorForm;
public class ArticleForm extends ValidatorForm
{
private int articleID = 0;
private String title = "";
private String content = "";
public int getArticleID() {
return articleID;
}
public void setArticleID(int a) {
this.articleID = a;
}
public String getTitle() {
return title;
}
public void setTitle(String t) {
this.title = t;
}
public String getContent() {
return content;
}
public void setContent(String c) {
this.content = c;
}
}
第三步:接下来就是Action类ArticleAction.java中的处理了,很简单,接着看:
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.swsoftware. forms.ArticleForm;
import org.apache.struts.action.Action;
import com.swsoftware.beans.Article;
public class ArticleAction extends Action
{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
HttpSession session = request.getSession();
ActionMessages errors = new ActionMessages();
ActionForward forward = new ActionForward(); // return value
ArticleForm articleForm = (ArticleForm) form;
String page = request.getParameter("page");//注意这里定义这个page变量是为了接
//收每次点击下一页传递过来的page参数,它代表当前页数
if (page == null || page.equals("null") || page.length() <= 0) {
page = "1";
}
Article article = new Article();
try {
List obj = article.query();
if (obj == null) {
errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
"errors.queryerror"));
}
if ("request".equals(mapping.getScope().toLowerCase()))
request.setAttribute("Article", obj);
else
session.setAttribute("Article", obj);
request.setAttribute("page", page);//把page保存在request中
request.setAttribute("totalPut", String.valueOf(obj.size()));//保存查询结果的总数//在
//totalPut中
} catch (Exception e) {
// Report the error using the appropriate name and ID.
errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
"errors.systemerror"));
e.printStackTrace();
}
if (!errors.isEmpty()) {
saveErrors(request, errors);
return (mapping.findForward(“failure”));
}
return (mapping.findForward(“success”));
}
}
然后我们在struts-config.xml写入:
然后我们在struts-config.xml写入:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans>
<form-bean name="articleform" type="com.swsoftware.hljhz.admin.forms.ArticleForm">
</form-bean>
</form-beans>
<global-exceptions />
<global-forwards>
<forward name="failure"
path="/Error.jsp">
</forward>
</global-forwards>
<action-mappings>
<action name="articleform" path="/article" scope="request"
type="com.swsoftware.actions.ArticleAction">
<forward name="success" path="/article.jsp"/>
</action>
</action-mappings>
</struts-config>
其实上面写了那么多都不是我们这篇文章的重要主题,之所以写上是为了方便一些初学者,以下的才是,请仔细看:
第四步:我们来写一个自定义的标签,用来在网页上打印分页的信息,分页的信息形式如下:
共 89 篇文章 首页 上一页 下一页 尾页 页次:1/5页 20篇文章/页 转到: 第1页第2页第3页第4页第5页
这个自定义的标签命名为PaginatorTag,代码如下:
package com.swsoftware.tags;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class PaginatorTag extends BodyTagSupport {
protected Log log = LogFactory.getLog(this.getClass());
//以下是一标签中的一些属性,后面有较详细的介绍
int currentPage = 1;
String url = "";
int totalPut = 0;
int maxPerPage = 20;
boolean showTotal = true;
boolean showAllPages = false;
String strUnit ="";
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getMaxPerPage() {
return maxPerPage;
}
public void setMaxPerPage(int maxPerPage) {
this.maxPerPage = maxPerPage;
}
public boolean isShowAllPages() {
return showAllPages;
}
public void setShowAllPages(boolean showAllPages) {
this.showAllPages = showAllPages;
}
public boolean isShowTotal() {
return showTotal;
}
public void setShowTotal(boolean showTotal) {
this.showTotal = showTotal;
}
public String getStrUnit() {
return strUnit;
}
public void setStrUnit(String strUnit) {
this.strUnit = strUnit;
}
public int getTotalPut() {
return totalPut;
}
public void setTotalPut(int totalPut) {
this.totalPut = totalPut;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int doStartTag() throws JspException {
return SKIP_BODY;
}
public int doEndTag() throws JspException {
String out = showPage(currentPage, url, totalPut, maxPerPage, showTotal, showAllPages, strUnit);
try {
pageContext.getOut().print(out);
} catch (IOException e) {
e.printStackTrace();
}
return EVAL_PAGE;
}
/**
* 作 用:显示“上一页 下一页”等信息
*
* @param url
* ----链接地址
* @param totalPut
* ----总数量
* @param maxPerPage
* ----每页数量
* @param showTotal
* ----是否显示总数量
* @param showAllPages
* ---是否用下拉列表显示所有页面以供跳转。有某些页面不能使用,否则会出现JS错误。
* @param strUnit
* ----计数单位
* @return .
* @throws IOException
*/
protected String showPage(int currentPage,String url, int totalPut, int maxPerPage,
boolean showTotal, boolean showAllPages, String strUnit){
int n = 0;
StringBuffer buf = new StringBuffer();
String strUrl;
if (totalPut % maxPerPage == 0)
n = totalPut / maxPerPage;
else
n = totalPut / maxPerPage + 1;
buf.append("<table align='center'><tr><td>");
if (showTotal == true)
buf.append("共 <b>" + totalPut + "</b> " + strUnit
+ " ");
strUrl = JoinChar(url);
if (currentPage < 2) {
buf.append("首页 上一页 ");
} else {
buf.append("<a href='" + strUrl + "page=1' title='首页'>首页</a> ");
buf.append("<a href='" + strUrl + "page=" + (currentPage - 1)
+ "' title='上一页'>上一页</a> ");
}
if (n - currentPage < 1)
buf.append("下一页 尾页");
else {
buf.append("<a href='" + strUrl + "page=" + (currentPage + 1)
+ "' title='下一页'>下一页</a> ");
buf.append("<a href='" + strUrl + "page=" + n + "' title='尾页'>尾页</a>");
}
buf.append(" 页次:<strong><font color=red>" + currentPage
+ "</font>/" + n + "</strong>页 ");
buf.append(" <b>" + maxPerPage + "</b>" + strUnit + "/页");
if (showAllPages == true) {
buf
.append(" 转到:<select name='page' size='1' onchange=\"javascript:window.location='"
+ strUrl
+ "page="
+ "'+this.options[this.selectedIndex].value;\">");
for (int i = 1; i <= n; i++) {
buf.append("<option value='" + i + "'");
if(currentPage == i)
buf.append(" selected ");
buf.append(">第" + i + "页</option>");
}
buf.append("</select>");
}
buf.append("</td></tr></table>");
return (buf.toString());
}
/**
* 向地址中加入 ? 或 &
* @param strUrl
* ----网址.
* @return 加了 ? 或 & 的网址.
*/
protected String JoinChar(String strUrl) {
String result = "";
if (strUrl.equals("") || strUrl.length() <= 0) {
return result;
}
if (strUrl.indexOf("?") < strUrl.length()) {
if (strUrl.indexOf("?") > -1) {
if (strUrl.indexOf("&") < strUrl.length()) {
result = strUrl + "&";
} else {
result = strUrl;
}
} else {
result = strUrl + "?";
}
} else {
result = strUrl;
}
return result;
}
}
有了自定义标签,当然少不了用于处理标签的tld,我们定义一个swsoft-struts.tld,代码如下:
有了自定义标签,当然少不了用于处理标签的tld,我们定义一个swsoft-struts.tld,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>out</shortname>
<uri>http://www.swsoftware.com/</uri>
<info>Tab Library for PaginatorTag</info>
<tag>
<name>paginator</name>
<tagclass>com.swsoftware.tags.PaginatorTag</tagclass>
<bodycontent>JSP</bodycontent>
<info>Returns a paginator</info>
<attribute>
<name>currentPage</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>url</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>totalPut</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>maxPerPage</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>showTotal</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>showAllPages</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>strUnit</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
第五步:好了,到现在我们开始来真正看一下jsp中的处理,我们写一个article.jsp,代码如下:
<%@ page contentType="text/html; charset=GBK" language="java"%>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<%@ taglib uri="/WEB-INF/swsoft-struts.tld"prefix="swtag"%> <%
final int maxPerPage = 20;// maxPerPage表示每页中显示的行数,可以随便取值,此处为20
int currentPage = (!request.getAttribute("page").equals(""))?Integer.parseInt(request.getAttribute("page").toString()):1;// currentPage表示当前页,当用户每次点击
//下一页或上一页时都会传递page参数,大家还记得前面
//的ArticleAction中定义了一个page参数,当用户点击下一页时,
//ArticleAction接收到page参数,并把它存在request中,然后由
//currentPage取得
int totalPut = request.getAttribute("totalPut")==null?0:Integer.parseInt(request.getAttribute("totalPut").toString());//取得查询结果的总数
if(currentPage<1)//如果currentPage小于一,让它等于1
currentPage=1;
if((currentPage-1)*maxPerPage>totalPut){//以下是处理currentPage的一些数学计算,大家仔细看一下就会明白
if((totalPut % maxPerPage)==0)
currentPage= totalPut / maxPerPage;
else
currentPage= totalPut / maxPerPage + 1;
}
%>
<html:html locale="true">
<head>
<title> </title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<link rel="stylesheet" type="text/css" href="Style.css">
<body leftmargin="2" topmargin="0" marginwidth="0" marginheight="0">
<table width='100%' border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<table class="border" border="0" cellspacing="1" width="100%"
cellpadding="0">
<tr class="title" height="22">
<td width="25" align="center" height="22"><strong>ID</strong></td>
<td align="center"><strong>文章标题</strong></td>
</tr>
<!—请注意以下部分! -->
<logic:iterate id="article" name="Article"
length="<%=String.valueOf(maxPerPage)%>"
offset="<%=String.valueOf((currentPage-1)*maxPerPage)%>">
<tr class="tdbg" onmouseout="this.style.backgroundColor=''"
onmouseover="this.style.backgroundColor='#BFDFFF'">
<td width="25" align="center"><bean:write name="article"
property="articleID" /></td>
<td>
<a href='<%=contextPath%>/showarticle.jsp?articleID=<bean:write
name="article" property="articleID"/>'><bean:write
name="article" property="title" filter="false"/></a></td>
</tr>
</logic:iterate>
</table>
</td>
</tr>
</table>
<swtag:paginator url="/article.do"
currentPage="<%=currentPage%>" totalPut="<%=totalPut%>"
maxPerPage="<%=maxPerPage%>" showTotal="true" showAllPages="true"
strUnit="篇文章" />
</body>
</html:html>
我们来看一下article.jsp中的<!—请注意以下部分! -->后面的代码
<logic:iterate id="article" name="Article"
length="<%=String.valueOf(maxPerPage)%>"
offset="<%=String.valueOf((currentPage-1)*maxPerPage)%>">
我们命名用Struts中的logic标签中的logic:iterate标签来迭代我们查询的结果,它的id和name属性我就不多说了,主要是lenth和offset属性,length属性表示每次迭代的长度,即显示的行数,我们把它设置为等于maxPerPage,offset属性表示迭代的偏移量,可以由以下表格理解:
currentPage
maxPerPage
Offset=(currentPage-1)*maxPerPage
1
20
0
2
20
20
3
20
40
4
20
60
当currentPage=1时,offset由0-19共20条记录,当currentPage=2时,offset由20-39共20条记录,当currentPage=3时,offset由40-59共20条记录,以此类推。
下面就是介绍中
<swtag:paginator url="/article.do"
currentPage="<%=currentPage%>" totalPut="<%=totalPut%>"
maxPerPage="<%=maxPerPage%>" showTotal="true" showAllPages="true"
strUnit="篇文章" />
了url="/article.do"表示每次点击下一页时连接的地址,currentPage、totalPut和maxPerPage就不用介绍了,showTotal表示是否显示总数量,showAllPages是否用下拉列表显示所有页面以供跳转。
好了,我们来总结一下:
文章中最重要的部分要算定义了一个自定义的标签PaginatorTag,用来在页面上打印分页的信息,然后在jsp中的最前面定义
<%
final int maxPerPage = 20;// maxPerPage表示每页中显示的行数,可以随便取值,此处为20
int currentPage = (!request.getAttribute("page").equals(""))?Integer.parseInt(request.getAttribute("page").toString()):1;// currentPage表示当前页,当用//户每次点击下一页或上一页时都会传递page参数,大家还记得前面的 //ArticleAction中定义了一个page参数,当用户点击下一页时,ArticleAction接//收到page参数,并把它存在request中,然后由currentPage取得
int totalPut = request.getAttribute("totalPut")==null?0:Integer.parseInt(request.getAttribute("totalPut").toString());//取得查询结果的总数
if(currentPage<1)//如果currentPage小于一,让它等于1
currentPage=1;
if((currentPage-1)*maxPerPage>totalPut){//以下是处理currentPage的一//些数学计算,大家仔细看一下就会明白
if((totalPut % maxPerPage)==0)
currentPage= totalPut / maxPerPage;
else
currentPage= totalPut / maxPerPage + 1;
}
%>
接下来是logic:iterate中设置length和offset属性,最后是在要显示分页信息的地方写上
<swtag:paginator url="/article.do"
currentPage="<%=currentPage%>" totalPut="<%=totalPut%>"
maxPerPage="<%=maxPerPage%>" showTotal="true" showAllPages="true"
strUnit="篇文章" />
大家只要把这些了解就可以很方便的处理Struts中的分面处理了!J