1. 什么是FreeMarker
FreeMarker是一个用于生成文本输出(例如HTML网页)的模板引擎。 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具
常见的模板引擎:JSP、Freemarker(简单,高效)、Thymeleaf(功能强大,效率低)
模板语法参考:
https://blog.csdn.net/m0_64210833/article/details/135994864
2. 常见作用
- 发邮件的时候通过模板文件动态生成html内容
3. SpringBoot集成
- 引入pom依赖
<!--freemarker依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
- 修改配置文件
spring:
freemarker:
cache: false # 关闭模板缓存
settings:
template_update_delay: 0 # 检查模板更新延迟时间,设置0标识立即检查,如果时间大于0会有缓存,不方便模板测试
suffix: .ftl # 执行Freemarker模板文件的后缀名
template-loader-path: classpath:/templates # 模板文件地址
- 实例代码
package com.tjx.controller;
import com.tjx.pojo.Student;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
*
* </p>
*
* @author tianjiaxin
* @createTime 2024/5/31 10:49
* @Description:
*/
//不能使用@RestController,因为是返回视图
@Controller
@RequestMapping("/demo")
public class DemoController {
@Autowired
private FreeMarkerConfig freeMarkerConfig;
// 方式一:通过SpringMVC直接返回视图
// SpringMVC将Freemarker作为视图解析器(ViewReporter)来集成到项目
// 注意:不能使用@RestController,因为是返回视图
@RequestMapping(value = "/t1", method = RequestMethod.GET)
public String test1(Model model) {
Student stu = new Student();
stu.setAge(18);
model.addAttribute("stu", stu);
// 文件名
return "01basic";
}
// 方式二:直接生成文本文件
@RequestMapping(value = "/t2", method = RequestMethod.GET)
public void test2() {
try {
Template template = freeMarkerConfig.getConfiguration().getTemplate("02list.ftl");
template.process(this.getData(), new FileWriter("d:/list1.html"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 方式三: 直接返回html字符串内容
@RequestMapping(value = "/t3", method = RequestMethod.GET)
public void test3() {
try {
Template template = freeMarkerConfig.getConfiguration().getTemplate("01basic.ftl");
Map<String, Student> map = new HashMap<>();
map.put("stu", new Student("小小", 18));
String s = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
System.out.println("============" + s);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Map getData() {
Map<String, Object> map = new HashMap<>();
//小强对象模型数据
Student stu1 = new Student();
stu1.setName("小强");
stu1.setAge(18);
//小红对象模型数据
Student stu2 = new Student();
stu2.setName("小红");
stu2.setAge(19);
//将两个对象模型数据存放到List集合中
List<Student> stus = new ArrayList<>();
stus.add(stu1);
stus.add(stu2);
//向map中存放List集合数据
map.put("stus", stus);
//创建Map数据
HashMap<String, Student> stuMap = new HashMap<>();
stuMap.put("stu1", stu1);
stuMap.put("stu2", stu2);
//向map中存放Map数据
map.put("stuMap", stuMap);
// 2.1 添加日期
// Date date = null;
Date date = new Date();
map.put("today", date);
//返回Map
return map;
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private String name;
private Integer age;
}
01basic.ftl
<#--文章详情模板文件-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World!</title>
</head>
<body>
<b>普通文本 String 展示:</b><br><br>
Hello ${stu.name!'-----------'} <br>
<hr>
<b>对象Student中的数据展示:</b><br/>
姓名(如果属性不存在则是空字符串):${(stu.name)!''}<br/>
年龄:${stu.age}
<hr>
</body>
</html>
02list.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World!</title>
</head>
<body>
<#-- list 数据的展示 -->
<b>展示list中的stu数据:</b>
<br>
<br>
<table>
<tr>
<td>序号</td>
<td>姓名</td>
<td>年龄</td>
<td>钱包</td>
</tr>
<#if stus??>
<#list stus as stu>
<#if stu.name=='小红'>
<tr style="color:#ff0000">
<td>${stu_index + 1}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
</tr>
<#else >
<tr>
<td>${stu_index + 1}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
</tr>
</#if>
</#list>
</#if>
stus集合的大小:${stus?size}
</table>
<hr>
<#-- Map 数据的展示 -->
<b>map数据的展示:</b>
<br/><br/>
<a href="###">方式一:通过map['keyname'].property</a><br/>
输出stu1的学生信息:<br/>
姓名:${stuMap['stu1'].name}<br/>
年龄:${stuMap['stu1'].age}<br/>
<br/>
<a href="###">方式二:通过map.keyname.property</a><br/>
输出stu2的学生信息:<br/>
姓名:${stuMap.stu2.name}<br/>
年龄:${stuMap.stu2.age}<br/>
<br/>
<a href="###">遍历map中两个学生信息:</a><br/>
<table>
<tr>
<td>序号</td>
<td>姓名</td>
<td>年龄</td>
<td>钱包</td>
</tr>
<#list stuMap?keys as key>
<tr>
<#--索引index是从0开始的-->
<td>${key_index + 1}</td>
<td>${stuMap[key].name}</td>
<td>${stuMap[key].age}</td>
</tr>
</#list>
</table>
<hr>
当前的日期为:${today?datetime}<br>
当前的日期为:${today?string("yyyy年MM月")}
-----------------------------------------------------<br>
<#--${point?c}-->
</body>
</html>