Tag Archive for 'freemarker'

利用FreeMarker实现类似google的分页效果

刚把上一篇Spring+Struts+Hibernate实现类似google的分页效果整理完,开始写下今天的主题文章,在freemarker下实现对分页的控制,其实最开始的打算是,直接调用以前写好的一个类库,然后再freemarker中调用自定义的标签来实现的,但是想想,算了,都写到这个份上了,还是直接写一个算了,对于以后的修改更为方便,恩,随着对freemarker的使用越来越频繁,真是发现这个东西太棒了,使view简化的不能再简化了,哈哈,偶喜欢。

代码部分很简洁,说下大致的处理流程:
运行环境是:Struts2+spring+ibatis
然后由ibatis–>spring–>struts2,再有struts2经过result到ftl文件,ftl文件中处理就可以了,具体的过程代码不再展示,这个很easy,也没什么展示的,无非就是dao,service,action之类的,写过来写过去没啥意思,把主要对分页处理的部分贴上来给大家看看。
代码中,pageCount,pageAfterNum,pageBeforeNum三项的值,是在后台设置上的,在系统启动时写入到applications中,所以可以不用任何获取就能直接使用,其他的话,要么经过request获取,要么就是计算得出的。好了,不扯了,直接贴上来好勒。

<#-- 分页 -->
<#macro pagePrint totalCount>
<#-- 获取相关参数,并把所有参数转换为数字类型,另外从applications中获取的也需要转换到数值型
当前页:indexPage,
总页数:totalPage,
当前页前显示页数:afterNum,
当前页后显示页数:beforeNum,
条件:where
-->
<#--获取当前页,如果没有当前页,则设置indexPage为1-->
<#assign indexPage = (request.getParameter('indexPage')!1)?eval />
<#assign totalPage = 1 />
<#assign afterNum = 1 />
<#assign beforeNum = 1 />
<#--获取参数,如果参数为null,则设置参数为空-->
<#assign where = (request.queryString!"") />
<#--处理条件中的indexPage参数,因每次都会自动获取indexPage,则需要截取掉该字符串,replace("","",""),最后一项r代表使用正则表达式替换-->
<#assign where = (where?replace("indexPa(.*?)&","","r"))>
<#assign pageCount = pageCount?eval />
<#assign pageAfterNum = pageAfterNum?eval />
<#assign pageBeforeNum = pageBeforeNum?eval />
<#--首先判断总页数-->
<#if totalCount % pageCount == 0>
<#assign totalPage = totalCount/pageCount>
<#else>
<#assign totalPage = totalCount/pageCount+1>
</#if>
<#--判断当前页前应显示多少数字-->
<#if indexPage lte pageAfterNum>
<#assign afterNum = indexPage - 1>
<#else>
<#assign afterNum = pageAfterNum>
</#if>
<#--判断当前页后应显示多少数字-->
<#assign beforeNum = indexPage + pageBeforeNum>
<#if beforeNum gt totalPage>
<#assign beforeNum = totalPage>
</#if>
<#--打印代码-->
<div id="pagePrint">
<span>共${totalCount}条/每页${pageCount}条</span>
<#--判断是否为第一页,如果不是第一页,则显示首页字样-->
<#if indexPage!=1>
<a href="?indexPage=1&${where}">首页</a><a href="?indexPage=${indexPage - 1}&${where}">上一页</a>
</#if>
<#--打印当前页码前显示的页码数-->
<#list afterNum..0 as i>
<#--判断是否到了0页,如果到,则退出-->
<#if i=0><#break></#if>
<a href="?indexPage=${indexPage-i}&${where}">${indexPage-i}</a>
</#list>
<#--打印当前页码-->
<span>${indexPage}</span>
<#--打印当前页码后显示的页码数-->
<#list (indexPage + 1)..beforeNum as i>
<#--判断当前页码是否大于了最终页,如果大于,则退出-->
<#if i gt beforeNum><#break></#if>
<a href="?indexPage=${i}&${where}">${i}</a>
</#list>
<#--判断是否到了最后一页,如果不是,则显示下一页,末页字样-->
<#if indexPage!=totalPage>
<a href="?indexPage=${indexPage + 1}&${where}">下一页</a><a href="?indexPage=${totalPage}&${where}">末页</a>
</#if>
</div>
<#--
测试输出:
totalPage:${totalPage}
afterNum:${afterNum}
beforeNum:${beforeNum}
-->
</#macro>

使用的时候直接<@pagePrint totalCount=200 />就可以了,传递的参数totalCount就是总记录数。

其实针对这段可以再分解开的,懒得弄了,告一段落,等到完全OK,做下期工作的时候再来整理吧,欢迎探讨,欢迎拍砖,欢迎XX。恩,你也可以到这里来转转,看下另外一篇关于分页的文章,不过建议还是不要看了,因为。。。算了,我还是看看吧。:)

Spring+Struts+Hibernate实现类似google的分页效果

其实这篇文章是很早很早以前写的了,当时放到了BlogJava上,结果由于后来偶在blogjava做了点不规矩的事(额,具体是什么就不说了),正好被咔嚓了,所有资料全部丢失,正好今天又要做分页,就google了下,顺便把这篇文章也摘回来了,代码很简单,主要就是判断那块,贴上来,给自己留个纪念。
Continue reading ‘Spring+Struts+Hibernate实现类似google的分页效果’

freemarker的力量太强大了

忍不住感慨下,虽然调试不太容易,但是出错很容易看出来,用于前台展示,very good!再次称赞下。:)

利用FreeMarker模板引擎创建动态调用

比较郁闷,这个标题不知道怎么起,以前写过关于FreeMarker生成静态页面,还有调用的一些文章,但这次好像又稍微有点不同,说不同呢,又差不多,搞得都不知道自己在捣鼓些什么了,- -#,暂且就这样说好了。

自己平常在用到一些程序的时候,比较喜欢关注程序的模板方面,现在大部分的程序都能实现了灵活的模板设计,将模板和程序分离开来,一直都在想在java下的解决方案,每次想到这块,脑子里第一就会想到FreeMarker,总感觉能实现,但自己又说不清楚怎么来实现,正好,今天有点时间,抽空自己写了个简单的实力来实现这个功能,就类似于说,我可以自己定义一个方法的调用,然后决定我调用多少条文章,是否调用置顶了之类的东东,唉,说是不好说,直接来代码好了。

主要的文件一共有三个,一个Servlet,一个标记解析的类,一个模板文件,代码如下:

package com.fm.study;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
* 访问的Servlet
*
* @author HuZhigang
* @date 2009-6-29
*/

public class FMDemo extends HttpServlet {

/**
*
*/
private static final long serialVersionUID = 8295505224176026191L;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

@SuppressWarnings("unchecked")
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
Configuration cfg = new Configuration();
//设置FreeMarker需要读取的模板路径
String path = this.getServletContext().getRealPath("/")
+ "WEB-INF\\ftl";
cfg.setDirectoryForTemplateLoading(new File(path));
cfg.setObjectWrapper(new DefaultObjectWrapper());
cfg.setDefaultEncoding("utf-8");
//模板文件名
Template temp = cfg.getTemplate("index.ftl");
Map root = new HashMap();
//写入一个变量,key对应value
root.put("user", "Hmilyld");
//创建一个回调变量
root.put("call", new CallFactory());
temp.process(root, out);
} catch (TemplateException e) {
e.printStackTrace();
}
}
}

代码很简单,主要就是读取模板文件然后输出就可以了,主要注意的是这句:root.put(“call”, new CallFactory());我们定义一个变量,然后可以调用我们的方法。

下面是我们需要操作的方法,CallFactory需要实现TemplateMethodModel这个接口,然后我们所传入的参数以List的形式传入,这个时候,可以读取List来获取我们相关传入的参数,代码如下:

package com.fm.study;

import java.util.ArrayList;
import java.util.List;

import com.fm.bean.ArticleBean;
import com.fm.bean.ProductBean;

import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;

/**
* 解析标记的相关方法
*
* @author HuZhigang
* @date 2009-6-29
*/

public class CallFactory implements TemplateMethodModel {

@SuppressWarnings("unchecked")
public Object exec(List arg0) throws TemplateModelException {
String type = (String) arg0.get(0);
if ("article".equals(type)) {
// 如果标记为article,则调用文章的相关方法
return article(arg0);
} else if ("product".equals(type)) {
// 如果标记为product,则调用商品的相关方法
return product(arg0);
} else {
throw new TemplateModelException("Error!");
}
}

/**
* 调用文章的相关方法
*
* @return
* @author HuZhigang
*/
private Object article(List<String> param) {
List<ArticleBean> list = new ArrayList<ArticleBean>();
int count = Integer.parseInt(param.get(1));
for (int i = 0; i < count; i++) {
ArticleBean ab = new ArticleBean();
ab.setTitle("这里是标题--" + i);
ab.setContent("这里是内容--" + i);
ab.setAuthor("这里是作者" + i);
ab.setUrl("这里是url--" + i);
list.add(ab);
}
return list;
}

/**
* 调用产品的相关方法
*
* @return
* @author HuZhigang
*/
private Object product(List<String> param) {
List<ProductBean> list = new ArrayList<ProductBean>();
int count = Integer.parseInt(param.get(1));
for (int i = 0; i < count; i++) {
ProductBean pb = new ProductBean();
pb.setName("这里是商品标题--" + i);
pb.setMeta("这里是商品简介--" + i);
pb.setPrice((float) Math.random());
list.add(pb);
}
return list;
}

}

OK,主要实现的功能都在这个里面了,当然,你可以完全拆分开,不同的类来实现不同的方法,具体应用就看自己怎么用了,可以按照传入的条件判断需要调用多少内容,是否固定,是否推荐等等内容

下面就是我们最后的模板文件,很简单

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>FreeMarker标记解析演示</title>
<style>
body{
font-size:12px;
}
#article,#product{
float:left;
margin:5px;
}
td{
width:120px;
}
</style>
</head>
<body>
<h1>Hello,${user}</h1>
<div id="main">
<div id="article">
<h2>文章列表演示</h2>
<#--根据创建的call,调用我们需要调用的方法,我们这里传入article类型,然后数量为20条 -->
<#assign article = call("article",20,"true")>
<table border="1">
<tr>
<td>标题</td>
<td>内容</td>
<td>作者</td>
<td>url</td>
</tr>
<#--循环打印出所有内容-->
<#list article as art>
<tr>
<td>${art.title}</td>
<td>${art.content}</td>
<td>${art.author}</td>
<td>${art.url}</td>
</tr>
</#list>
</table>
</div>
<div id="product">
<h2>商品列表演示</h2>
<#--调用类型为商品,20条数据-->
<#assign product = call("product",20)>
<table border="1">
<tr>
<td>名称</td>
<td>价格</td>
<td>简介</td>
</tr>
<#list product as pro>
<tr>
<td>${pro.name}</td>
<td>${pro.price}</td>
<td>${pro.meta}</td>
</tr>
</#list>
</table>
</div>
</div>
</body>
</html>

OK,搞定,主要就是这么多的操作,还有其他的一些高级的应用,根据实际情况来自己修改,偶也没深入的去研究,只是翻开FreeMarker的API来看了下,大致的一个功能实现,嘿,对后面自己需要写的一个东西是用处大大啊。

哈哈,利用FreeMaker模板引擎生成静态HTML,搞定啦.

哈哈,前段时间一直在想这个事情,不过没怎么去研究,
手里的活催的比较紧一些,
这两天稍微松了下,找了下资料开始研究FreeMarker,
网上搜了下,国内的资料少的可怜。无奈,MSN上找了个朋友问下,
人家也忙啊,撇过来句,看英文的文档去,例子什么都有,看两遍就会了.
寒,我那英文水平..- -#
硬着头皮看了看,又找了点其他的资料瞅瞅,
吼吼,真TMD的简单啊,(这个简单说的仅限于生成啊,其他地方,设置编码什么的,还没看呢.- -#)
你能想到的,开源项目里面的人都给你想到了,从数据的类型,
到你需要输出的什么东西,太神奇勒..
这几天写个完整的例子出来看看,
其实一直困扰的分页问题,也没那么难解决,如果用静态的话,
可以完全抛弃Jpager了,用不到那个东西了,用输出来判断就完全可以了.

HOHO,纯静态哦,嘎嘎,我笑…

PS:例子等几天放上来好了,其实还是推荐看官方的文档,太详细了..


无觅相关文章插件,快速提升流量