<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">这几天看了freemarker的一点学习心得。</span>
之前项目做过静态分页,是ajax取出数据结合jquery分页,发现有时会出现数据不分页展示的情况。这个问题一直困扰了很久,后来发现了freemarker中的分页技术,静态页面毕竟是趋势,比起和数据库打交道静态分页的所提交请求较少。
这里展示一个新闻列表的分页和下拉框分页
根据freemaker模板+数据模型的生成要求,我们先指定数据的生成,这里不采取和数据库连接,直接用静态类生成要用的数据,
/**
*
*/
package com.freemarker.news;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author lenovo
*
*/
public class Data{
public static List<News> datalist=new ArrayList<>();
static{
for(int id=1;id<12;id++){
datalist.add(new News(id,"新闻"+id,new Date(),"作者"+id));
}
}
public static void main(String[] args) {
for (News s : datalist) {
System.out.println(s.getName());
}
}
}
Data类中datalist即为我们要的数据。
我们再制定一个实体类存放新闻的内容News
/**
*
*/
package com.freemarker.news;
import java.util.Date;
/**
* 新闻实体类
* @author lenovo
*
*/
public class News {
private int id;
private String name;
private Date date;
private String author;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
/**
* @param id
* @param name
* @param date
* @param author
*/
public News(int id, String name, Date date, String author) {
super();
this.id = id;
this.name = name;
this.date = date;
this.author = author;
}
/**
*
*/
public News() {
// TODO Auto-generated constructor stub
}
}
有了新闻实体,我们还需要封装一个页的新闻数据,这里在写一个类pager
/**
*
*/
package com.freemarker.news;
import java.util.List;
/**
* 封装分页数据
* @author lenovo
*
* @param <E>
*/
public class Pager<E> {
private List<E> data;
private int page;
private int totalnum;
private int totalpage;
private int numOfpage;
private int currentNum;
public List<E> getData() {
return data;
}
public void setData(List<E> data) {
this.data = data;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
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 int getNumOfpage() {
return numOfpage;
}
public void setNumOfpage(int numOfpage) {
this.numOfpage = numOfpage;
}
public int getCurrentNum() {
return currentNum;
}
public void setCurrentNum(int currentNum) {
this.currentNum = currentNum;
}
}
其中data为一页的新闻数据,是个List集合,
page指代当前页码 ,currentNum为当前页的新闻数目,numOfpage为一页的数目,这里我们是指定的3,修改每页数目可以修改代码中的该属性值,totalpage和totalnum分别为总页数和新闻总数。
有了实体类和封装的分页数据类,我们还要提供一个接口类去获取数据中的属性值,因此再新建一个dao类
<pre name="code" class="java">/**
*
*/
package com.freemarker.news;
import java.util.ArrayList;
import java.util.List;
/**
* @author lenovo
*
*/
public class NewsDao {
private int numOfpage = 3;
public int getTotalnum(){
return Data.datalist.size();
}
public int getTotalPage(){
if((getTotalnum()%numOfpage)==0){
return getTotalnum()/3;
}
return getTotalnum()/3+1;
}
public Pager<News> getNews(int curPage) {
Pager<News> pager = new Pager<>();
pager.setPage(curPage);
pager.setTotalnum(getTotalnum());
pager.setTotalpage(getTotalPage());
pager.setNumOfpage(numOfpage);
List<News> data = new ArrayList<>();
for(int i=(curPage-1)*numOfpage;i<curPage*numOfpage;i++)
{
if(i==getTotalnum()){
break;
}
data.add(Data.datalist.get(i));
}
pager.setData(data);
pager.setCurrentNum(data.size());
return pager;
}
/**
* test
* @param args
*/
public static void main(String[] args) {
NewsDao dao = new NewsDao();
Pager<News> pager = dao.getNews(2);
System.out.println( "页数"+dao.getTotalPage());
for (News ss : pager.getData()) {
System.out.println(ss.getName());
}
}
}
到此我们完成了数据分页的所有工作,下面就是模板引擎了。 接着我们制作出我们的模板文件news,ftl,和所需的分页模板文件common,ftl
news.ftl通过include指令将common,ftl包含进来,
common.ftl中含有两个自定义指令page 和 select分别用来处理分页请求和下拉框请求
<#include "common.ftl">
<!DOCTYPE type>
<html>
<head>
<title>
新闻列表
</title>
<script type="text/javascript">
window.οnlοad=function(){
document.getElementById("ss").value="${pager.page}"
}
</script>
</head>
<body>
<table border="1" align="center" width="50%">
<tr>
<td>id</td>
<td>名字</td>
<td>日期</td>
<td>作者</td>
</tr>
<#list pager.data as d>
<tr>
<td>${d.id}</td>
<td>${d.name}</td>
<td>${d.date?date}</td>
<td>${d.author}</td>
</tr>
</#list>
</table>
<div class="" align="center">
<@page totalPage=pager.totalpage url="news_list" currpage=pager.page/>
<@select id="ss" totalpage=pager.totalpage url="news_list"/>
</div>
</body>
</html>
<#--分页自定义指令-->
<#macro page totalPage url currpage = 1>
<#list 1..totalPage as p>
<#if p = currpage>
${p}页
<#else>
<a href="${url}_${p}.html">${p}</a>
</#if>
</#list>
</#macro>
<#macro select id totalpage url>
<select id="${id}" onChange="javascript:location.href='${url}_'+this.value+'.html'">
<#list 1..totalpage as p>
<option value="${p}">${p}</option>
</#list>
</select>
</#macro>
最后,我们开始写主方法啦
/**
*
*/
package com.freemarker.news;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
* @author lenovo
*
*/
public class NewsMain {
/**
* @param args
* @throws IOException
* @throws TemplateException
*/
public static void main(String[] args) throws TemplateException, IOException {
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File("src/com/ftl"));
Template template = cfg.getTemplate("news.ftl");
NewsDao dao = new NewsDao();
int totalpage = dao.getTotalPage();
for (int i = 1; i <= totalpage; i++) {
Pager<News> pager = dao.getNews(i);
Writer writer = new FileWriter(new File("news_list_"+i+".html"));
Map<String, Pager<News>> rootMap = new HashMap<String, Pager<News>>();
rootMap.put("pager", pager);
template.process(rootMap, writer);
}
}
}
最后的效果是