要学习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>
重新运行测试方法,然后重新刷新静态页面,如下图所示,可以看到正常展示出页脚内容了。
有了这些语法,我们便可以制作出各种各样的模板了。