也显示一下我的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,则去掉1url = url.substring(0, url.length() - 1);} else if (url.lastIndexOf("/") != url.length() - 1) {// 如果没有页码1,并且最后不是'/'时,加上'/'url = url + "/";}}} else {url = url.substring(0, url.lastIndexOf("/") + 1);}}// 下面这段处理主要是用来处理动态查询的参数,并拼接成urlStringBuffer 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;@Overrideprotected 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);}@Overridepublic 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" styletheme="text" queryParames="queryParames"></fly:pages></td>? 就这样简单一个通用的分页框架就完成了。
12 楼 風一樣的男子 2010-01-31 看到 ListAction 里那么多实例变量就讨厌