论坛首页 Java企业应用论坛

写了一个freemarker的分页macro

浏览 19181 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-11-02  



刚学了一下freemarker,觉得他的macro相当好用,就写了一个分页的功能
pagination.ftl
<#macro pagination totalCount pageSize>
    <#--声明一个函数transform 转换uri,在新的uri上pager_offset参数  -->
	<#assign transform = "util.TransformURI"?new()>
	<#--声明一个函数,得到当前页码-->
	<#assign pagerOffset = "util.PagerOffset"?new()>
	<#--声明一个函数,根据传入的totalCount,pageSize得到总页数-->
	<#assign pagerCount = "util.PageCount"?new()>
	<#assign pageCount=pagerCount(totalCount,pageSize)>
	<#--得到当前的URI和请求参数,得到当前的页码-->
	<#if request.queryString?exists>
		<#assign uri=request.requestURI+"?"+request.queryString>
		<#assign pageIndex=pagerOffset(uri)>
		<#assign new_uri=transform(uri)>
	<#else>
		<#assign uri=request.requestURI>
		<#assign pageIndex=pagerOffset(uri)>
		<#assign new_uri=transform(uri)>
	</#if>
	<#if (pageIndex>pageCount)>
		<#assign pageIndex=pageCount>
	</#if>
    <#if (pageIndex>1)>
        <a href="${new_uri+1}" title="首页">&lt;&lt;</a>
    </#if>
    <#--如果前面页数过多,显示"..."-->
    <#if (pageIndex>5)>
        <#assign prevPages=pageIndex-9>
        <#if prevPages lt 1>
        	<#assign prevPages=1>
        </#if>
        <#assign start=pageIndex-4>
        <a href="${new_uri+prevPages}" title="向前5页">...</a>
    <#else>
        <#assign start=1>
     </#if>
    <#-- 显示当前页附近的页-->
    <#assign end=pageIndex+4>
    <#if (end>pageCount)>
    	<#assign end=pageCount>
    </#if>
    <#list start..end as index>
    	<#if pageIndex==index>
    		<b>${index}</b>
    	<#else>
    		<a href="${new_uri+index}">${index}</a>
    	</#if>
    </#list>
    <#--如果后面页数过多,显示"...":-->
    <#if (end lt pageCount)>
    	<#assign end=end+5>
    	<#if (end>pageCount)>
    		<#assign end=pageCount>
    	</#if>
    	<a href="${new_uri+end}" title="向后5页">...</a>
    </#if>
    <#-- 显示"下一页":-->
    <#if (pageIndex lt pageCount)>
    	<a href="${new_uri+pageCount}" title="末页">&gt;&gt;</a>
    </#if>
</#macro>

我自定义了三个方法:
PageCount.java
package util;

import java.util.List;

import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
/**
 * 根据传入的参数,计算出所有的页数
 * @author legolas
 */
public class PageCount implements TemplateMethodModel {

	@Override
	public Object exec(List args) throws TemplateModelException {
		Integer totalCount = 0;
		Integer pageSize = 0;
		try {
			totalCount = Integer.parseInt((String) args.get(0));
			pageSize = Integer.parseInt((String) args.get(1));
		} catch (NumberFormatException e) {
			throw new TemplateModelException("请输入正确的总记录数和页面记录数");
		}
		Integer pageCount = totalCount / pageSize
				+ (totalCount % pageSize == 0 ? 0 : 1);
		return pageCount;
	}

}


TransformURI.java
package util;

import java.util.List;

import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
/**
 * 根据传入的uri,在uri后面加上分页参数
 * @author legolas
 *
 */
public class TransformURI implements TemplateMethodModel{

	@Override
	public Object exec(List args) throws TemplateModelException {
		String uri = (String) args.get(0);
		int n = uri.lastIndexOf("?");
		if (n == -1) {
			return uri + "?pager_offset=";
		}
		if (uri.lastIndexOf("?pager_offset") != -1) {
			uri = uri.substring(0, uri.lastIndexOf("=") + 1);
			return uri;
		}
		String queryString = uri.substring(n + 1, uri.length());
		String suburi = uri.substring(0, n + 1);
		String[] strings = queryString.split("&");
		for (int i = 0; i < strings.length; i++) {
			if (strings[i].startsWith("pager_offset")) {
				continue;
			}
			suburi += strings[i];
			suburi += "&pager_offset=";
		}
		return suburi;
	}
	
	
	
}

PagerOffset.java
package util;

import java.util.List;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
/**
 * 得到当前的页码
 * @author legolas
 *
 */
public class PagerOffset implements TemplateMethodModel {

	@Override
	public Object exec(List args) throws TemplateModelException {
		String uri = (String) args.get(0);
		String[] string = uri.split("pager_offset=");
		if (string.length == 1) {
			return 1;
		} else {
			Integer pager_offset = 1;
			try {
				pager_offset = Integer.parseInt(string[1]);
			} catch (NumberFormatException e) {
				pager_offset = 1;
			}
			return pager_offset;
		}
	}
}


在页面上宏的调用
<DIV class=PageNum>
			<#import "pagination.ftl" as com>
			<#--前一个参数是总记录数,后一个参数是页面记录数-->
			<@com.pagination Request.totalCount Request.pageSize/>
		</div>

Css文件
.PageNum {
	MARGIN: 5px 0px;
	TEXT-ALIGN: left
}

.PageNum B {
	BORDER-RIGHT: #f60 1px solid;
	PADDING-RIGHT: 5px;
	BORDER-TOP: #f60 1px solid;
	PADDING-LEFT: 5px;
	BACKGROUND: url(../images/link_bg2.gif) repeat-x;
	PADDING-BOTTOM: 2px;
	MARGIN: 10px 0px 10px 2px;
	BORDER-LEFT: #f60 1px solid;
	COLOR: #f30;
	LINE-HEIGHT: 20px;
	PADDING-TOP: 2px;
	BORDER-BOTTOM: #f60 1px solid
}

.PageNum A {
	BORDER-RIGHT: #5c8 1px solid;
	PADDING-RIGHT: 5px;
	BORDER-TOP: #5c8 1px solid;
	PADDING-LEFT: 5px;
	BACKGROUND: url(../images/link_bg1.gif) repeat-x;
	PADDING-BOTTOM: 2px;
	MARGIN: 10px 0px 10px 2px;
	BORDER-LEFT: #5c8 1px solid;
	LINE-HEIGHT: 20px;
	PADDING-TOP: 2px;
	BORDER-BOTTOM: #5c8 1px solid
}

.PageNum A:link {
	COLOR: #183
}

.PageNum A:visited {
	COLOR: #183
}

.PageNum A:hover {
	BACKGROUND: url(../images/link_bg2.gif) repeat-x;
	COLOR: #f60
}

使用这个宏非常的简便,只需要传入总记录和页面大小就可以分页,其他的都已经封装好了。关于freemarker自定义方法,可以去官方文档上面查看,另外新版本的freemarker自定义指令实现接口有所改动,提醒。。。
  • 大小: 13.6 KB
  • 大小: 13.9 KB
   发表时间:2008-11-02  
不是吧,lz,我正写这个呢,而且风格都一样……太汗了
代码都差不多,不过我的view是纯tag的,没那么多java代码,唯一的一个就是Page这个抽象对象,与数据库结合比较容易。

总之,赞个,也太巧合了。。。
0 请登录后投票
   发表时间:2008-11-02  
key232323 写道

不是吧,lz,我正写这个呢,而且风格都一样……太汗了代码都差不多,不过我的view是纯tag的,没那么多java代码,唯一的一个就是Page这个抽象对象,与数据库结合比较容易。总之,赞个,也太巧合了。。。

view是纯tag的,功能相对弱点吧,要传入更多的参数吗?想看看你的实现。。。贴部分代码出来吧。。哈
0 请登录后投票
   发表时间:2008-11-03  
很早以前就写了一个freemarker分页。纯web。只有PaginationSupport一个类来充当VO。
传入参数可以直接通过xx=oo&cc=bb的形式传啊。
另外分页组件一般都要支持form提交,以便保存查询条件。
0 请登录后投票
   发表时间:2008-11-04  
刚学java没多久,在学校的时候写asp。正在学jsp中的jsptag,想写个分页类。但是构思总是设计不好。不知道该如何架构读取模块。今天第一次看到还有这样可以分页。比较疑惑的是只传入总记录和页面大小就可以分页时如何实现的?如果用假分的话是可以,但怎么做到真分呢?即第一次查询出所有其余就只查询各页的。最好能很容易扩展比如很容膝实现分页显示xml数据
0 请登录后投票
   发表时间:2008-11-04   最后修改:2008-11-05
用总记录和页面大小就可以知道一共有多少页了,每次将当前页值传入后台,可以用
limit 语句

取出你需要的数据就可以了。
1 请登录后投票
   发表时间:2008-11-06  
key232323 写道

不是吧,lz,我正写这个呢,而且风格都一样……太汗了代码都差不多,不过我的view是纯tag的,没那么多java代码,唯一的一个就是Page这个抽象对象,与数据库结合比较容易。总之,赞个,也太巧合了。。。

其实用velocity模版语言写出来的分页也是差不多这个格式的`````
感觉velocity的使用好象没freemarker这么复杂````不过功能上面没有freemarker多``但是已经够用啦  嘿嘿```
0 请登录后投票
   发表时间:2008-11-06  
再支持你一下

http://www.iteye.com/topic/263263

自己摸索着写的。欢迎拍砖
1 请登录后投票
   发表时间:2008-11-11  
晕,太麻烦了
1 请登录后投票
   发表时间:2008-11-11  
太棒了,好好研究一下
http://yongtree.iteye.com/admin/blogs/264227
我改造的struts2分页组件,欢迎拍砖。
1 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics