要学习freemarker就要学习它的语法,下面我们便依次来学习freemarker的常用语法。
第一个语法:Pojo的使用
首先创建一个Pojo类Student,如下图所示
Pojo类代码如下:
package com.taotao.freemarker;
public class Student {
private int id;
private String name;
private int age;
private String address;
public Student(int id, String name, int age, String address) {
super();
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
public Student(){}
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
下面我们便针对这个Pojo来创建一个新的模板student.ftl,如下图所示
模板代码如下:
<html>
<head>
<title>测试页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
学生信息:<br>
学号:${student.id}<br>
姓名:${student.name}<br>
年龄:${student.age}<br>
住址:${student.address}<br>
</body>
</html>
下面对上节课的测试类代码做下修改,如下图所示。
测试类代码如下:
package com.taotao.freemarker;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class TestFreeMarker {
@Test
public void testFreeMarker() throws Exception{
//1.创建一个模板文件(就是我们刚创建的hello.ftl模板)
//2.创建一个Configuration对象
Configuration configuration = new Configuration(Configuration.getVersion());
//3.设置模板所在的路径
configuration.setDirectoryForTemplateLoading(new File("E:/taotao/workspace/taotao-item-web/src/main/webapp/WEB-INF/ftl"));
//4.设置模板的字符集,一般为utf-8
configuration.setDefaultEncoding("utf-8");
//5.使用Configuration对象加载一个模板文件,需要指定模板文件的文件名。
//Template template = configuration.getTemplate("hello.ftl");
Template template = configuration.getTemplate("student.ftl");
//6.创建一个数据集,可以是pojo也可以是map,推荐使用map
Map data = new HashMap<>();
data.put("hello", "hello freemarker");
Student student = new Student(1, "张三", 20, "北京市海淀区西二旗");
data.put("student", student);
//7.创建一个Writer对象,指定输出文件的路径及文件名
Writer out = new FileWriter(new File("E:/freemarker/out/student.html"));
//8.使用模板对象的process方法输出文件
template.process(data, out);
//9.关闭流
out.close();
}
}
运行上面的测试方法后会在E:/freemarker/out/目录下生成一个student.html页面,我们双击在浏览器中查看,发现出现乱码了。
这是由于文件的编码格式不是utf-8造成的,原来的编码是GBK,而我们的代码中设置的编码格式是UTF-8,因此需要将文件的编码格式也变成UTF-8,如下图所示。
student.ftl文件编码改成utf-8后,原来写的内容就又变成乱码了,我们把模板内容清空再重新粘贴如下模板内容。
<html>
<head>
<title>测试页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
学生信息:<br>
学号:${student.id}<br>
姓名:${student.name}<br>
年龄:${student.age}<br>
住址:${student.address}<br>
</body>
</html>
然后我们再重新运行上面的测试方法,然后重新刷新页面,可以看到乱码解决了。而且我们可以正常看到Pojo类中的信息了。
第二种语法:循环
在测试类中添加一个集合,在模板中循环遍历这个集合,如下图所示
测试类添加的代码如下:
List<Student> stuList = new ArrayList<>();
stuList.add(new Student(1, "小米", 20, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(2, "小米2", 21, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(3, "小米3", 22, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(4, "小米4", 23, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(5, "小米5", 24, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(6, "小米6", 25, "北京市昌平区小米科技有限公司"));
data.put("stuList", stuList);
模板添加的代码如下,循环的语法是"<#"后面接集合,"as stu"中的"stu"是当前循环到的对象
学生列表:<br>
<table border="1">
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>地址</th>
</tr>
<#list stuList as stu>
<tr>
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.address}</td>
</tr>
</#list>
</table>
添加完代码之后,运行测试方法,成功后,我们再刷新静态网页,如下图所示。正常展示出了学生列表。
第三种语法:循环下标的获取
对于列表展示,如果我们想获取行的下标的话,用freemarker很容易实现,为了直观的查看下标,我们在模板的列表展示中添加一列"序号",值的话就直接使用当前对象及下划线和index如下图所示,便可以获取。
当前模板文件代码如下:
<html>
<head>
<title>测试页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
学生信息:<br>
学号:${student.id}<br>
姓名:${student.name}<br>
年龄:${student.age}<br>
住址:${student.address}<br>
学生列表:<br>
<table border="1">
<tr>
<th>序号</th>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>地址</th>
</tr>
<#list stuList as stu>
<tr>
<td>${stu_index}</td>
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.address}</td>
</tr>
</#list>
</table>
</body>
</html>
修改完后,我们重新运行测试方法,然后重新刷新静态页面,可以看到正确展示出了每行的下标。
第四种语法:if条件的使用
在列表展示当中经常用到隔行变色的效果,隔行变色就要用到if判断,如果是奇数行就用某种颜色,偶数行就用另外一种颜色。比如我现在想把奇数行背景颜色变为红色,把偶数行背景颜色变为蓝色,语法是"<#if"后面加判断条件,else在if条件之间(这点与我们平时的java习惯不一致)else书写语法是<#else>,如下图所示。
当前模板代码如下:
<html>
<head>
<title>测试页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
学生信息:<br>
学号:${student.id}<br>
姓名:${student.name}<br>
年龄:${student.age}<br>
住址:${student.address}<br>
学生列表:<br>
<table border="1">
<tr>
<th>序号</th>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>地址</th>
</tr>
<#list stuList as stu>
<#if stu_index%2==0>
<tr bgcolor="red">
<#else>
<tr bgcolor="blue">
</#if>
<td>${stu_index}</td>
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.address}</td>
</tr>
</#list>
</table>
</body>
</html>
修改完后重新运行测试方法,然后重新刷新静态页面,可以看到已经展现出隔行变色的效果了。
第五种语法:日期处理
我们先来看默认情况下日期的展示效果,在测试类中添加一行代码(把日期加入map当中),在模板中把日期取出来,如下图所示。
修改完后,运行代码,会看到如下图所示的错误,告诉我们无法将日期转换为string类型,并且在"Tip"当中告诉了我们可以通过在date后面加?date或?time或?datetime来将日期类型转换为string。
既然告诉了我们应该怎么办,我们就按照上面的提示,先在模板的date后面加?date,如下所示。
日期处理类型:${date?date}
修改完后运行测试方法,然后重新刷新静态网页,可以看到如下图所示界面,在页面最下方展示出了日期,只是日期的格式是以"-"分隔的。
我们还可以把date后面换成?time和?datetime,这样输出的日期分别为"21:12:23"和"2017-5-16 21:12:50"。可以发现,展示的日期格式是比较固定的,那么如果我们想按自己想要的方式展示日期,该怎么办?这个其实刚才报错信息中已经给出提示信息了,如下图所示,明确的告诉了我们可以在date后面加?string('yyyy/MM/dd HH:mm:ss')来展示我们的日期。
模板中date展示改成如下代码
日期处理类型:${date?string('yyyy/MM/dd HH:mm:ss')}
重新运行测试方法并重新刷新静态网页,如下图所示,发现正常按照我们的想法进行展示了。
第六种语法:null值的处理
在页面展示时有可能遇到null的处理,如果我们展示一个不存在的变量的话,就会变错,如下图所示,在最下方添加展示不存在的变量。
运行测试代码,会出现运行错误,错误消息提示展示的内容是null或者不存在,要解决这个问题,"Tip"给出了提示信息,告诉我们可以在变量后面加"!默认值"。
模板对于变量的展示做以下修改:
null值的处理:${var!"默认值"}
运行测试方法并重新刷新静态页面,如下图所示。正常展示出了"默认值"。
还有一种处理null值的方法是使用if判断。
添加的代码如下:
<br>
null值的处理:${var!"默认值"}
<br>
使用if判断null值:
<#if val??>
var是有值的
<#else>
var是Null
</#if>
运行测试代码,然后重新刷新静态页面,可以看到输出了"var是Null"。
我们现在让var变量有值,方法是在测试方法中添加data.put("var","123");如下图所示。
当前测试类的所有代码如下:
package com.taotao.freemarker;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class TestFreeMarker {
@Test
public void testFreeMarker() throws Exception{
//1.创建一个模板文件(就是我们刚创建的hello.ftl模板)
//2.创建一个Configuration对象
Configuration configuration = new Configuration(Configuration.getVersion());
//3.设置模板所在的路径
configuration.setDirectoryForTemplateLoading(new File("E:/taotao/workspace/taotao-item-web/src/main/webapp/WEB-INF/ftl"));
//4.设置模板的字符集,一般为utf-8
configuration.setDefaultEncoding("utf-8");
//5.使用Configuration对象加载一个模板文件,需要指定模板文件的文件名。
//Template template = configuration.getTemplate("hello.ftl");
Template template = configuration.getTemplate("student.ftl");
//6.创建一个数据集,可以是pojo也可以是map,推荐使用map
Map data = new HashMap<>();
data.put("hello", "hello freemarker");
Student student = new Student(1, "张三", 20, "北京市海淀区西二旗");
data.put("student", student);
List<Student> stuList = new ArrayList<>();
stuList.add(new Student(1, "小米", 20, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(2, "小米2", 21, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(3, "小米3", 22, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(4, "小米4", 23, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(5, "小米5", 24, "北京市昌平区小米科技有限公司"));
stuList.add(new Student(6, "小米6", 25, "北京市昌平区小米科技有限公司"));
data.put("stuList", stuList);
//日期类型
data.put("date", new Date());
//给变量赋值
data.put("var","123");
//7.创建一个Writer对象,指定输出文件的路径及文件名
Writer out = new FileWriter(new File("E:/freemarker/out/student.html"));
//8.使用模板对象的process方法输出文件
template.process(data, out);
//9.关闭流
out.close();
}
}
运行测试方法然后重新刷新静态页面,可以看到var已经有值了。
第七种语法:添加页眉页脚
静态页面中最常见的是页眉和页脚的内容是固定的,这意味着我们不必要重复写页眉页脚,只需要各写一遍,然后需要的时候引入进来就可以了。我们举个例子,把上节课写的模板作为页脚添加进来。如下图所示。
当前模板全部代码如下:
<html>
<head>
<title>测试页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
学生信息:<br>
学号:${student.id}<br>
姓名:${student.name}<br>
年龄:${student.age}<br>
住址:${student.address}<br>
学生列表:<br>
<table border="1">
<tr>
<th>序号</th>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>地址</th>
</tr>
<#list stuList as stu>
<#if stu_index%2==0>
<tr bgcolor="red">
<#else>
<tr bgcolor="blue">
</#if>
<td>${stu_index}</td>
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.address}</td>
</tr>
</#list>
</table>
<br>
日期处理类型:${date?string('yyyy/MM/dd HH:mm:ss')}
<br>
null值的处理:${var!"默认值"}
<br>
使用if判断null值:
<#if var??>
var是有值的
<#else>
var是Null
</#if>
<br>
页脚的添加:
<#include "hello.ftl">
</body>
</html>
重新运行测试方法,然后重新刷新静态页面,如下图所示,可以看到正常展示出页脚内容了。
有了这些语法,我们便可以制作出各种各样的模板了。