淘淘商城第81讲——freemarker的语法

我们要学习freemarker,就得学习它的语法,下面我会为大家详细介绍freemarker的常用语法。

访问Map中的key

上一讲已经介绍过了,故在此并不过多赘述。

访问pojo中的属性

首先创建一个pojo类,例如Student.java,如下图所示。
在这里插入图片描述
为了方便大家复制,现将以上Student类的代码给出,如下所示。

package com.taotao.freemarker;

public class Student {

    private int id;
    private String name;
    private int age;
    private String address;
    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;
    }
    public Student() {

    }
    public Student(int id, String name, int age, String address) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

}

然后我们便针对这个pojo来创建一个新的模板,例如template.htm,如下图所示。
在这里插入图片描述
为了方便大家复制,现将template.htm模板的内容贴出,如下所示。

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
		<title>${title}</title>
	</head>
	
	<body>
		id:${student.id}
		name:${student.name}
		<br/>
		id:${student1.id}
		name:${student1.name}
		<br/>
		id:${student2.id}
		name:${student2.name}
	</body>
</html>

接着对FreemarkerTest单元测试类中的testFreemarker方法做下修改,如下图所示。
在这里插入图片描述
为了方便大家复制,现将以上单元测试类的代码给出,如下所示。

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 FreemarkerTest {

	private static final String directorpath = "D:/Practise/taotao/taotao-item-web/src/test/resources/template";

	// 生成静态页面的方法
	@Test
	public void testFreemarker() throws Exception {
		// 模板 + 数据 → 输出到静态页面
		
		// 1. 创建Configuration对象
		Configuration configuration = new Configuration(Configuration.getVersion());
		// 2. 设置模板文件所在的目录,可以是任意的目录
		configuration.setDirectoryForTemplateLoading(new File(directorpath));
		// 3. 设置字符集
		configuration.setDefaultEncoding("utf-8");
		// 4. 创建一个模板文件,官方提供的文件后缀名是.ftl,其实任意的后缀名都是可以的
		// 5. 加载模板文件,获取模板对象,写的是相对路径的文件名
		Template template = configuration.getTemplate("template.htm");
		// 6. 创建数据集,可以使用Map或者pojo,一般使用Map
		Map model = new HashMap();
		model.put("title", "测试freemarker的语法");
		
		// 创建三个Student对象
		Student student = new Student(1, "赢荡", 35, "秦国");
		Student student1 = new Student(2, "嬴政", 45, "秦国");
		Student student2 = new Student(3, "赢稷", 25, "秦国");
		
		model.put("student", student);
		model.put("student1", student1);
		model.put("student2", student2);
		
		// 7. 创建Writer输出流
		Writer writer = new FileWriter(new File("D:/项目实战/淘淘商城/freemarker/hello.html"));
		// 8. 通过调用模板对象中的process方法输出
		template.process(model, writer);
		// 9. 关闭流
		writer.close();
	}
	
}

运行上面的测试方法后,会在D:\项目实战\淘淘商城\freemarker目录下生成一个hello.html的页面,我们双击它在浏览器中查看,可以正常看到pojo类中的属性,如下图所示。
在这里插入图片描述
如果模型数据中设置的值是1000以上,例如我们将如下三个Student对象中id属性的值设置为1000以上,那么会发生什么现象呢?
在这里插入图片描述
此时,运行FreemarkerTest单元测试类中的测试方法之后,使用浏览器打开生成的hello.html页面,你会发现id的值出现了千分位,如下图所示。
在这里插入图片描述
这对于咱国人来说,看起来很不习惯,咱压根就不想看到这个千分位,又不是数不过来。那么如何去掉这个千分位呢?可以使用?c语法来去除,就像下面这样。
在这里插入图片描述
再次运行FreemarkerTest单元测试类中的测试方法,并使用浏览器打开生成的hello.html页面,此时你会发现千分位没了,如下图所示。
在这里插入图片描述

取List集合中的数据

首先对FreemarkerTest单元测试类中的测试方法做下修改,在该测试方法中添加一个List集合,如下图所示。
在这里插入图片描述
为了方便大家复制,现将以上单元测试类的代码给出,如下所示。

package com.taotao.freemarker;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
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 FreemarkerTest {

	private static final String directorpath = "D:/Practise/taotao/taotao-item-web/src/test/resources/template";

	// 生成静态页面的方法
	@Test
	public void testFreemarker() throws Exception {
		// 模板 + 数据 → 输出到静态页面
		
		// 1. 创建Configuration对象
		Configuration configuration = new Configuration(Configuration.getVersion());
		// 2. 设置模板文件所在的目录,可以是任意的目录
		configuration.setDirectoryForTemplateLoading(new File(directorpath));
		// 3. 设置字符集
		configuration.setDefaultEncoding("utf-8");
		// 4. 创建一个模板文件,官方提供的文件后缀名是.ftl,其实任意的后缀名都是可以的
		// 5. 加载模板文件,获取模板对象,写的是相对路径的文件名
		Template template = configuration.getTemplate("template.htm");
		// 6. 创建数据集,可以使用Map或者pojo,一般使用Map
		Map model = new HashMap();
		model.put("title", "测试freemarker的语法");
		
		// 创建三个Student对象
		Student student = new Student(1, "赢荡", 35, "秦国");
		Student student1 = new Student(2, "嬴政", 45, "秦国");
		Student student2 = new Student(3, "赢稷", 25, "秦国");
		
		model.put("student", student);
		model.put("student1", student1);
		model.put("student2", student2);
		
		// List集合
		List<Student> list = new ArrayList<Student>();
		list.add(student);
		list.add(student1);
		list.add(student2);
		
		model.put("list", list);
		
		// 7. 创建Writer输出流
		Writer writer = new FileWriter(new File("D:/项目实战/淘淘商城/freemarker/hello.html"));
		// 8. 通过调用模板对象中的process方法输出
		template.process(model, writer);
		// 9. 关闭流
		writer.close();
	}
	
}

然后我们要循环取List集合中的数据,使用的语法为<#list 集合 as 循环的变量>···</#list>,例如:

<#list list as student>
	${student.id}/${studnet.name}
</#list>

所以,我们应将template.htm模板的内容修改为:

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
		<title>${title}</title>
	</head>
	
	<body>
		id:${student.id}
		name:${student.name}
		<br/>
		id:${student1.id}
		name:${student1.name}
		<br/>
		id:${student2.id}
		name:${student2.name}
		<br/>
		学生列表:
		<br/>
		<table border="1">
			<tr>
				<th>学号</th>
				<th>姓名</th>
				<th>年龄</th>
				<th>家庭住址</th>
			</tr>
			<#list list as student>
				<tr>
					<td>${student.id}</td>
					<td>${student.name}</td>
					<td>${student.age}</td>
					<td>${student.address}</td>
				</tr>
			</#list>
		</table>
	</body>
</html>

运行testFreemarker测试方法,成功后,我们再刷新hello.html静态网页,如下图所示,正常展示出了学生列表。
在这里插入图片描述

取循环中的下标

对于列表展示,如果我们想获取行的下标的话,用freemarker很容易实现,为了直观的查看下标,我们在模板的列表展示中添加"序号"这一列,值的话就直接使用当前对象及下划线和index便可以获取,如下图所示。
在这里插入图片描述
为了方便大家复制,现将template.htm模板的内容贴出,如下所示。

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
		<title>${title}</title>
	</head>
	
	<body>
		id:${student.id}
		name:${student.name}
		<br/>
		id:${student1.id}
		name:${student1.name}
		<br/>
		id:${student2.id}
		name:${student2.name}
		<br/>
		学生列表:
		<br/>
		<table border="1">
			<tr>
				<th>序号</th>
				<th>学号</th>
				<th>姓名</th>
				<th>年龄</th>
				<th>家庭住址</th>
			</tr>
			<#list list as student>
				<tr>
					<td>${student_index}</td>
					<td>${student.id}</td>
					<td>${student.name}</td>
					<td>${student.age}</td>
					<td>${student.address}</td>
				</tr>
			</#list>
		</table>
	</body>
</html>

修改完后,我们重新运行测试方法,然后重新刷新静态页面,可以看到正确展示出了每行的下标。
在这里插入图片描述

取Map集合中的数据

首先对FreemarkerTest单元测试类中的测试方法做下修改,在该测试方法中添加一个Map集合,如下图所示。
在这里插入图片描述
然后我们就要循环取Map集合中的数据了,一共有两种方式可以取Map集合中的数据,咱们先来看第一种方式,使用的语法形式如下:

<#list map?keys as key>
	${map[key].id}---${map[key].name}
</#list>

所以,按照这种方式,我们应将template.htm模板的内容修改为:

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
		<title>${title}</title>
	</head>
	
	<body>
		id:${student.id}
		name:${student.name}
		<br/>
		id:${student1.id}
		name:${student1.name}
		<br/>
		id:${student2.id}
		name:${student2.name}
		<br/>
		学生列表:
		<br/>
		<table border="1">
			<tr>
				<th>序号</th>
				<th>学号</th>
				<th>姓名</th>
				<th>年龄</th>
				<th>家庭住址</th>
			</tr>
			<#list list as student>
				<tr>
					<td>${student_index}</td>
					<td>${student.id}</td>
					<td>${student.name}</td>
					<td>${student.age}</td>
					<td>${student.address}</td>
				</tr>
			</#list>
		</table>
		<br/>
		第一种方式:取Map集合中的数据<br/>
		<#list map?keys as key>
			${map[key].id}
			${map[key].name}
			<br/>
		</#list>
	</body>
</html>

运行testFreemarker测试方法,成功后,我们再刷新hello.html静态网页,效果如下图所示。
在这里插入图片描述
再来看看第二种取Map集合中数据的方式,其实很简单,只须将template.htm模板的内容修改成下面这个样子即可。

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
		<title>${title}</title>
	</head>
	
	<body>
		id:${student.id}
		name:${student.name}
		<br/>
		id:${student1.id}
		name:${student1.name}
		<br/>
		id:${student2.id}
		name:${student2.name}
		<br/>
		学生列表:
		<br/>
		<table border="1">
			<tr>
				<th>序号</th>
				<th>学号</th>
				<th>姓名</th>
				<th>年龄</th>
				<th>家庭住址</th>
			</tr>
			<#list list as student>
				<tr>
					<td>${student_index}</td>
					<td>${student.id}</td>
					<td>${student.name}</td>
					<td>${student.age}</td>
					<td>${student.address}</td>
				</tr>
			</#list>
		</table>
		<br/>
		第一种方式:取Map集合中的数据<br/>
		<#list map?keys as key>
			${map[key].id}
			${map[key].name}
			<br/>
		</#list>
		第二种方式:取Map集合中的数据<br/>
		${map.s1.id}
		${map.s1.name}<br/>
		${map.s2.id}
		${map.s2.name}<br/>
		${map.s3.id}
		${map.s3.name}<br/>
		${map.s4.id}
		${map.s4.name}<br/>
	</body>
</html>

然后再运行testFreemarker测试方法,成功后,我们再刷新hello.html静态网页,效果如下图所示。
在这里插入图片描述

if条件的使用

在列表展示当中经常要用到隔行变色的效果,隔行变色就要用到if条件判断,如果是奇数行就用某种颜色,偶数行就用另外一种颜色。比如我现在想把奇数行背景颜色变为蓝色,把偶数行背景颜色变为红色,语法为:

<#if student_index % 2 == 0>
	...
<#else>
	...
</#if>

这样,我们就要修改template.htm模板了,修改之后如下图所示。
在这里插入图片描述
为了方便大家复制,现将template.htm模板的内容给出,如下所示。

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
		<title>${title}</title>
	</head>
	
	<body>
		id:${student.id}
		name:${student.name}
		<br/>
		id:${student1.id}
		name:${student1.name}
		<br/>
		id:${student2.id}
		name:${student2.name}
		<br/>
		学生列表:
		<br/>
		<table border="1">
			<tr>
				<th>序号</th>
				<th>学号</th>
				<th>姓名</th>
				<th>年龄</th>
				<th>家庭住址</th>
			</tr>
			<#list list as student>
				<#if student_index % 2 == 0>
					<tr bgcolor="blue">
				<#else>
					<tr bgcolor="red">
				</#if>
						<td>${student_index}</td>
						<td>${student.id}</td>
						<td>${student.name}</td>
						<td>${student.age}</td>
						<td>${student.address}</td>
					</tr>
			</#list>
		</table>
		<br/>
		第一种方式:取Map集合中的数据<br/>
		<#list map?keys as key>
			${map[key].id}
			${map[key].name}
			<br/>
		</#list>
		第二种方式:取Map集合中的数据<br/>
		${map.s1.id}
		${map.s1.name}<br/>
		${map.s2.id}
		${map.s2.name}<br/>
		${map.s3.id}
		${map.s3.name}<br/>
		${map.s4.id}
		${map.s4.name}<br/>
	</body>
</html>

修改完后重新运行测试方法,然后重新刷新静态页面,可以看到已经展现出隔行变色的效果了。
在这里插入图片描述

日期类型格式化

我们先来看看默认情况下日期的展示效果,在FreemarkerTest单元测试类的测试方法中添加一行代码(即把日期加入map当中),如下图所示。
在这里插入图片描述
然后在template.htm模板中把日期取出来,如下图所示。
在这里插入图片描述
修改完后,运行testFreemarker测试方法,会看到如下图所示的错误,告诉我们无法将日期转换为string类型,并且在"Tip"当中告诉了我们可以通过在date后面加?date?time?datetime来将日期类型转换为string。
在这里插入图片描述
既然告诉了我们应该怎么办,那么我们就按照上面的提示,在模板的date后面加上?date?time?datetime,如下所示。

当前日期:${date?date}
<br/>
当前时间:${date?time}
<br/>
当前日期和时间:${date?datetime}

修改完后运行testFreemarker测试方法,再重新刷新一下静态网页,可以看到在页面最下方展示出了我们要看到的东西。
在这里插入图片描述
从上图中可以发现,展示的日期格式是比较固定的,如果我们想按自己想要的方式来展示日期,那么该怎么办呢?这个其实刚才报错信息中已经给出提示信息了,如下图所示,明确的告诉了我们可以在date后面加?string('yyyy/MM/dd HH:mm:ss')来展示我们的日期。
这里写图片描述
因此,我们再在template.htm模板中添加如下代码:

<br/>
自定义日期格式:${date?string("yyyy/MM/dd HH:mm:ss")}

然后重新运行testFreemarker测试方法并重新刷新静态网页,如下图所示,发现正常按照我们的想法进行展示了。
在这里插入图片描述

Null值的处理

处理方式一

在页面展示时有可能会遇到null值的处理,如果我们展示一个不存在的变量的话,那么就会报错,如下图所示,在最下方展示一个不存在的变量。
在这里插入图片描述
运行testFreemarker方法,会出现如下图所示的错误,错误消息提示展示的内容是null或者不存在,要解决这个问题,"Tip"给出了提示信息,告诉我们可以在变量后面加!默认值
在这里插入图片描述
因此,我们在template.htm模板中对于变量的展示做以下修改:

null值的测试:${keynull!"如果是空,我就应该出现在这里"}

再次运行测试方法并重新刷新静态页面,可以看到正常展示出了默认值,如下图所示。
在这里插入图片描述

处理方式二

知道了以上对null值的处理方式之后,我们也可以在template.htm模板中对变量的展示做以下修改:

null值的测试:${keynull!""}

运行testFreemarker方法,并重新刷新静态页面,效果如下图所示。
在这里插入图片描述

处理方式三

我们也可以在template.htm模板中对变量的展示做以下修改:

null值的测试:${keynull!}

运行testFreemarker方法,并重新刷新静态页面,效果如下图所示。
在这里插入图片描述

处理方式四

还有一种处理null值的方式是使用if条件判断。这时,我们就要修改template.htm模板了,修改之后如下图所示。
在这里插入图片描述
运行测试方法,然后重新刷新静态页面,效果如下图所示。
在这里插入图片描述
我们现在让keynull变量有值,方法是在testFreemarker测试方法中添加上下图所示的这行代码。
在这里插入图片描述
再次运行测试方法然后重新刷新静态页面,可以看到如下图所示的效果。
在这里插入图片描述

处理方式五

其实,还有一种处理null值的方式也是使用if条件判断。这时,我们将template.htm模板修改成下面这个样子。
在这里插入图片描述
然后运行testFreemarker方法,并重新刷新静态页面,效果将如下图所示。
在这里插入图片描述

include标签

静态页面中最常见的是页眉和页脚的内容是固定的,这意味着我们没必要重复写页眉和页脚,只需要各写一遍即可,然后某个页面需要的时候引入进来就可以了。在这里,我举个例子,把上一讲所写的模板include进来,如下图所示。
在这里插入图片描述
为了方便大家复制,现将template.htm模板的内容给出,如下所示。

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
		<title>${title}</title>
	</head>
	
	<body>
		<#include "hello.ftl" />
		<br/>
		id:${student.id}
		name:${student.name}
		<br/>
		id:${student1.id}
		name:${student1.name}
		<br/>
		id:${student2.id}
		name:${student2.name}
		<br/>
		学生列表:
		<br/>
		<table border="1">
			<tr>
				<th>序号</th>
				<th>学号</th>
				<th>姓名</th>
				<th>年龄</th>
				<th>家庭住址</th>
			</tr>
			<#list list as student>
				<#if student_index % 2 == 0>
					<tr bgcolor="blue">
				<#else>
					<tr bgcolor="red">
				</#if>
						<td>${student_index}</td>
						<td>${student.id}</td>
						<td>${student.name}</td>
						<td>${student.age}</td>
						<td>${student.address}</td>
					</tr>
			</#list>
		</table>
		<br/>
		第一种方式:取Map集合中的数据<br/>
		<#list map?keys as key>
			${map[key].id}
			${map[key].name}
			<br/>
		</#list>
		第二种方式:取Map集合中的数据<br/>
		${map.s1.id}
		${map.s1.name}<br/>
		${map.s2.id}
		${map.s2.name}<br/>
		${map.s3.id}
		${map.s3.name}<br/>
		${map.s4.id}
		${map.s4.name}<br/>
		
		当前日期:${date?date}
		<br/>
		当前时间:${date?time}
		<br/>
		当前日期和时间:${date?datetime}
		<br/>
		自定义日期格式:${date?string("yyyy/MM/dd HH:mm:ss")}
		<br/>
		null值的测试:${keynull!"如果是空,我就应该出现在这里"}
		<br/>
		null值的测试:${keynull!""}
		<br/>
		null值的测试:${keynull!}
		<br/>
		null值的判断:
		<#if keynull??>
			不为空,我就应该出现在这里
		<#else>
			为空,我就应该出现在这里
		</#if>
		<br/>
		null值的判断:
		<#if keynull?exists>
			不为空,我就应该出现在这里
		<#else>
			为空,我就应该出现在这里
		</#if>
	</body>
</html>

在运行testFreemarker测试方法之前,将该测试方法中的model.put("hello", "Hello World!");这句代码前的注释去掉,如下图所示。
在这里插入图片描述
然后再运行该测试方法,接着重新刷新静态页面,如下图所示,可以看到正常展示出所包含的内容了。
在这里插入图片描述
至此,freemarker的语法我就算是介绍一遍了,知道了这些语法之后,我们便可以制作出各种各样的模板了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李阿昀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值