也显示一下我的Struts2分页

  最近看见网上有不少基于Struts2+spring分页的东西,自己感觉都不是很适合,许多都只是对一个列表进行了分页,而没有考虑到查询条件等。个人认为,分页就是从前台把查询条件输入进去然后返回查询结果列表。这个问题的难点就是查询条件的传递,因为第一次查询时候需要输入查询条件,而以后点下一页时候,就不需要再次输入查询条件了。所以,第一次查询时候,需要把查询条件保存到某个地方,再次查询时候,把条件取出来,同时,这些要做的通用,等有许多查询页面时候,能最大限度的重用代码,好了,废话少说,下面展示我的分页代码

首先写一个Pages类,用来保存分页的一些信息,包括当前页码、记录总数、总页数、每页显示的记录数、查询条件等。代码如下:

public class Pages {
	private int pageNo = 1; // 当前页码

	private int totalNum = -1;// 记录总数

	private int totalPage = -1; // 总页数

	int perPageNum = 10; // 每页显示记录数

	private String queryParames;// 查询条件

	public String getQueryParames() {
		return queryParames;
	}

	public void setQueryParames(String queryParames) {
		this.queryParames = queryParames;
	}

	public Pages() {
	}

	public Pages(int pageNo, int totalNum, int perPageNum) {
		this.pageNo = pageNo;
		this.totalNum = totalNum;
		this.perPageNum = perPageNum;
		this.executeCount();
	}

	public void executeCount() {
		this.totalPage = (int) Math.ceil((this.totalNum + this.perPageNum - 1)
				/ this.perPageNum);
		if (this.totalPage <= 0) {
			this.totalPage = 1;
		}
		int intPage = this.pageNo;
		if (intPage > this.totalPage) {
			this.pageNo = this.totalPage;
		} else {
			this.pageNo = intPage;
		}
	}

	public int getPageNo() {
		return pageNo;
	}

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

	public int getPerPageNum() {
		return perPageNum;
	}

	public void setPerPageNum(int perPageNum) {
		this.perPageNum = perPageNum;
	}

	public int getTotalNum() {
		return totalNum;
	}

	public void setTotalNum(int totalNum) {
		this.totalNum = totalNum;
	}

	public int getTotalPage() {
		return totalPage;
	}

	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}

	public Map transQueryCondition() {
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNull(queryParames)) {
			return map;
		}
		String[] condtions = queryParames.split(";");
		for (int i = 0; i < condtions.length; i++) {
			if (StringUtils.isNull(condtions[i])) {
				continue;
			}
			map.put(condtions[i].split(",")[0], condtions[i].split(",")[1]);
		}
		return map;
	}

 下面写一个通用的Action类,用来初始化查询参数:

public abstract class ListAction extends ActionSupport {
	protected static final String LIST = "list";

	Logger logger = Logger.getLogger(ListAction.class);

	/*
	 * 当前页
	 */
	private int pageNo = 1;

	/*
	 * 总页数
	 */
	private int totalPage = -1;

	/*
	 * 总记录数
	 */
	private int totalNum = -1;

	/*
	 * 查询参数
	 */
	private String queryParames;

	private PageList pageList;

	public final String execute() {
		initQuerycondition();
		Pages pages = new Pages();
		pages.setPageNo(this.getPageNo());
		pages.setPerPageNum(10);
		pages.setTotalNum(totalNum);
		pages.executeCount();
		this.setTotalPage(pages.getTotalPage());
		pages.setQueryParames(queryParames);
		queryPageList(pages);
		this.setTotalPage(pages.getTotalPage());
		this.setTotalNum(pages.getTotalNum());
		return LIST;
	}

	/**
	 * 实现每个查询结果列表,依据查询结果的不同而不同
	 * @param pages
	 */
	protected abstract void queryPageList(Pages pages);

	/**
	 * 初始化查询参数的配置
	 */
	protected void initQuerycondition() {
		/*
		 *如果不是第一次查询,直接返回,否则设置查询参数,拼装成 queryParames
		 */
		if (totalNum >= 0) {
			return;
		}
		Map map = ActionContext.getContext().getParameters();
		Iterator iter = map.keySet().iterator();
		StringBuffer query = new StringBuffer();
		while (iter.hasNext()) {
			String key = (String) iter.next();
			Object keyValue = ((Object[]) map.get(key))[0];
			String value = "";
			if (!StringUtils.isObjNull(keyValue)) {
				query.append(";").append(key);
				if (keyValue instanceof Date) {
					value = DateUtils.trunsDateToString((Date) keyValue);
				} else {
					value = String.valueOf(keyValue);
				}
				query.append(",").append(value);
			}
		}
		this.setQueryParames(query.toString());
	}

//get.....set...方法	
}

再写一个Page类,继承Component,用来获取ValueStack中的参数值。

public class Page extends Component {
	private static final Log logger = LogFactory.getLog(Page.class);
	public Page(ValueStack stack) {
		super(stack);
	}

	private String pageNo; // 当前页码

	private String totalPage; // 总页数

	private String totalNum; // 总记录数

	private String styleClass; // 分页的样式

	private String theme; // 分页的主题

	private String url; // action的路径

	private String urlType; // 路径的类型,主要用于URL重写的扩展

	private String queryParames;

	public String getQueryParames() {
		return queryParames;
	}

	public void setQueryParames(String queryParames) {
		this.queryParames = queryParames;
	}

	public boolean start(Writer writer) {
		boolean result = super.start(writer);
		
		Object obj = this.getStack().findValue(pageNo);

		pageNo = String.valueOf((Integer) obj);

		obj = this.getStack().findValue(totalPage);

		totalPage = String.valueOf((Integer) obj);

		obj = this.getStack().findValue(totalNum);
		totalNum = 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 pageStr = "?totalNum=" + totalNum + "&pageNo=";

		if ("dir".equals(urlType)) {
			pageStr = "";

			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("");
		obj = this.getStack().findValue(queryParames);
		if (!StringUtils.isObjNull(obj)) {
			perUrl.append("&").append("queryParames").append("=").append(
					StringUtils.decode((String) obj));
		}
		
		//当前页
		Integer cpageInt = Integer.valueOf(pageNo);
		str.append("<span> ");
		// 文本样式
		if (theme == null || "text".equals(theme)) {
			// 当前页与总页数相等
			if (pageNo.equals(totalPage)) {
				// 如果total = 1,则无需分页,显示“[第1页] [共1页]”
				if ("1".equals(totalPage)) {
					str.append("[第 " + pageNo + " 页]");

					str.append(" [共 " + totalPage + " 页]");

				} else {

					// 到达最后一页,显示“[首页] [上一页] [末页]”
					str.append("<a href='" + url + pageStr + "1" + perUrl
							+ "'>[首  页]</a> ");

					str.append("<a href='" + url + pageStr + (cpageInt - 1)
							+ perUrl + "'>[上一页]</a>");

					str.append("[下一页]");

					str.append(" <a href='" + url + pageStr + totalPage
							+ perUrl + "'>[末  页]</a> ");

				}

			} else {

				// 当前页与总页数不相同
				if ("1".equals(pageNo)) {

					// 第一页,显示“[首 页] [下一页] [末页]”

					str.append("<a href='" + url + pageStr + "1" + perUrl
							+ "'>[首  页]</a>");
					str.append("[上一页]");
					str.append("<a href='" + url + pageStr + (cpageInt + 1)
							+ perUrl + "'>[下一页]</a>");
					str.append("<a href='" + url + pageStr + totalPage + perUrl
							+ "'>[末  页]</a>");

				} else {

					// 不是第一页,显示“[首页] [上一页] [下一页] [末页]”

					str.append("<a href='" + url + pageStr + "1" + perUrl
							+ "'>[首  页]</a>");

					str.append("<a href='" + url + pageStr + (cpageInt - 1)
							+ perUrl + "'>[上一页]</a>");

					str.append("<a href='" + url + pageStr + (cpageInt + 1)
							+ perUrl + "'>[下一页]</a>");

					str.append("<a href='" + url + pageStr + totalPage + perUrl
							+ "'>[末  页]</a>");

				}

			}

		} else if ("number".equals(theme)) { // 数字样式 [1 2 3 4 5 6 7 8 9 10 >											// >>]
			Integer totalInt = Integer.valueOf(totalPage);
			// 如果只有一页,则无需分页
			str.append("[ ");
			if (totalInt == 1) {
				str.append("<strong>1</strong> ");
			} else {
				//当前页
				if (cpageInt > 1) {
					// 当前不是第一组,要显示“<< <”
					// <<:返回前一组第一页
					// <:返回前一页
					str.append("<a href='" + url + pageStr + "1" + perUrl
							+ "'> << </a> ");
					str.append("<a href='" + url + pageStr + (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 - 10;
					v = (v <= 0 ? 1 : v); // 如果为负数,则修改为1

				} else if (v == 1 && v1 < totalInt) {
					v1 = totalInt > 10 ? 10 : totalInt;
				}
				// 10个为一组显示
				for (int i = v; i <= v1; i++) {
					if (cpageInt == i) { // 当前页要加粗显示
						str.append("<strong>" + i + "</strong> ");
					} else {
						str.append("<a href='" + url + pageStr + i + perUrl
								+ "'>" + i + "</a> ");
					}
				}
				// 如果多于1组并且不是最后一组,显示“> >>”

				if (cpageInt < totalInt) {

					// >>:返回下一组最后一页

					// >:返回下一页

					str.append("<a href='" + url + pageStr + (cpageInt + 1)
							+ perUrl);

					str.append("'>></a> ");

					str.append("<a href='" + url + pageStr + totalInt + perUrl);

					str.append("'> >> </a> ");

				} else {

					str.append("> >> ");

				}

			}
			str.append("]");
		}
		str.append("</span>");

		try {
			writer.write(str.toString());
		} catch (IOException e) {
			logger.error(e);
		}
		return result;
	}
//get set 方法区
}

 PageTag类,继承Struts2标签的 ComponentTagSupport。

public class PageTag extends ComponentTagSupport {
	private static final long serialVersionUID = -5371048231966321759L;

	private String pageNo;

	private String totalPage;

	private String totalNum;

	private String styleClass;

	private String theme;

	private String url;

	private String urlType;

	private String queryParames;

	@Override
	protected void populateParams() {

		super.populateParams();

		Page page = (Page) component;

		page.setPageNo(pageNo);

		page.setTotalPage(totalPage);
		page.setTotalNum(totalNum);
		page.setStyleClass(styleClass);

		page.setTheme(theme);

		page.setUrl(url);

		page.setUrlType(urlType);
		page.setQueryParames(queryParames);
	}

	@Override
	public Component getBean(ValueStack stack, HttpServletRequest request,
			HttpServletResponse response) {
		return new Page(stack);
	}

// get set 方法.......
}

 自定义分页的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>fly</short-name>
	<uri>/fly</uri>
	<display-name>"fly Tags"</display-name>
	<tag>
		<name>pages</name>
		<tag-class>com.fly.web.taglib.PageTag</tag-class>
		<body-content>jsp</body-content>
		<description>分页标签</description>
		<attribute>
			<name>pageNo</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>totalPage</name>
		<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>总页数</description>
		</attribute>
		<attribute>
			<name>totalNum</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>总记录数。</description>
		</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>			
		</attribute>
		<attribute>
			<name>queryParames</name>
			<required>false</required>
			<rtexprvalue>false</rtexprvalue>
		<description>
				查询参数
			</description>
		</attribute>
	</tag>
</taglib>  

 

  我们在jsp页面直接写

<td align="center" nowrap>
  记录总数
<s:property value="%{totalNum}" />条  每页显示10条
第<s:property value="pageNo" />页  <fly:pages pageNo="pageNo" totalPage="totalPage" totalNum="totalNum" styleClass="page" theme="text"  queryParames="queryParames">	</fly:pages>
</td>

  就这样简单一个通用的分页框架就完成了。

你可能感兴趣的:(oracle,sql,框架,mysql,jsp)