FreeMarker入门

一、什么是 FreeMarker?

  FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。而FreeMarker最初的设计,是被用来在MVC模式的Web开发框架中生成HTML页面的,它没有被绑定到 Servlet或HTML或任意Web相关的东西上。它也可以用于非Web应用环境中。

  模板文件存放在Web服务器上,就像通常存放静态HTML页面那样。当有人来访问这个页面, FreeMarker将会介入执行,然后动态转换模板,用最新的数据内容替换模板中 ${..} 的部分, 之后将结果发送到访问者的Web浏览器中。

  访问者的Web浏览器就会接收到例如第一个HTML示例那样的内容 (也就是没有FreeMarker指令的HTML代码),访问者也不会察觉到服务器端使用的FreeMarker。 (当然,存储在Web服务器端的模板文件是不会被修改的;替换也仅仅出现在Web服务器的响应中。)

二、语法指令

1)基础语法种类

  • 注释,即 <#-- -->,介于其之间的内容会被freemarker忽略
  • 插值(Interpolation):即 ${..} 部分,freemarker会用真实的值代替${..}
  • <# >FTL指令</#>  和HTML标记类似,名字前加#予以区分,Freemarker会解析标签中的表达式或逻辑
  • 文本,不是freemarker的注释、插值、FTL指令的内容会被freemarker忽略解析,直接输出内容

2)集合指令(List和Map)

  • 如果是list集合中存储了多个student对象,可以通过<#list></#list>指令遍历集合

${stu_index+1}   index:得到循环的下标,使用方法是在stu后边加"_index",它的值是从0开始

<#list stus as stu>
<tr>
<td>${stu_index+1}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.money}</td>
</tr>
</#list>

 

  • 如果是map集合中value又是一个map对象,也是通过<#list></#list>指令遍历map集合
<#list stuMap?keys as key >
<tr>
<td>${key_index + 1}</td>
<td>${stuMap[key].name}</td>
<td>${stuMap[key].age}</td>
<td>${stuMap[key].money}</td>
</tr>
</#list>

 

3)if指令

   if 指令即判断指令,是常用的FTL指令,freemarker在解析时遇到if会进行判断,条件为真则输出if中间的内容,否则跳过内容不再输出。

<#list stus as stu >
<#if stu.name='小红'>
<tr style="color: red">
<td>${stu_index}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.money}</td>
</tr>
<#else >
<tr>
<td>${stu_index}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.money}</td>
</tr>
</#if>
</#list>

 

三、入门使用

1)导入依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

 2) 创建项目

  a、项目结构图:

 

b、实体类和SpringBoot启动类就不再复述;freemarker.ftl 模板文件如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World!</title>
</head>
<body>
<b>普通文本 String 展示:</b><br><br>
Hello ${name!'====='}<br>
<hr>
<b>对象Student中的数据展示:</b><br/>
姓名:${(stu.name)!''}<br/> <#-- ${name!''}表示如果name为空显示空字符串-->
年龄:${stu.age}
<hr>
当前日期:${today?date}<br> <#--显示年月日: ${today?date}-->
当前日期:${today?time}<br>
当前日期:${today?datetime}<br>
当前日期:${today?string("yyyy年MM月")}<br><#--自定义格式化:${today?string("yyyy年MM月")}-->
整数:${point} <#--point是数字型,使用${point}会显示这个数字的值,每三位使用逗号分隔。-->
字符串:${point?c}<#--如果不想显示为每三位分隔的数字,可以使用c函数将数字型转成字符串输出 指令:${point?c}-->
<br>
</body>
</html>

c、application.yml 配置文件如下:

server:
port: 8881 #服务端口
spring:
application:
name: freemarker-demo #指定服务名
freemarker:
cache: false #关闭模板缓存,方便测试
settings:
template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试
suffix: .ftl #指定Freemarker模板文件的后缀名
template-loader-path: classpath:/templates #指定模板文件存放的位置

d、运行测试代码:

package com.heima.freemarker.test;
import com.heima.freemarker.FreemarkerApp;
import com.heima.freemarker.pojo.Student;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.FileWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest(classes = FreemarkerApp.class)
@RunWith(SpringRunner.class)
public class FreemarkerTest {
@Autowired
private Configuration configuration;
//通过模板文件,填充数据后生成一个html文件
@Test
public void test() throws Exception{
//指定模板文件,创建模板对象
Template template = configuration.getTemplate("freemarker.ftl");
/**
* 第一个参数:模型数据
* 第二个参数:输出流
*/
template.process(getData(),new FileWriter("d:\\index.html"));
}
private Map<String,Object> getData(){
Map<String,Object> map = new HashMap<>();
// map.put("name","freemarker");
//学生对象
Student student = new Student();
student.setName("张三");
student.setAge(18);
map.put("stu",student);
//日期类型
map.put("today",new Date());
//长整型
map.put("point",38743874387983398L);
return map;
}
}

e、打开 d:\index.html 路径下的html文件,效果如下:

四、与thymeleaf比较

  • 从写代码的角度看,freemarker更习惯于我们的思维。
  • 从前后分离开发的角度看thymeleaf更合适,值的绑定都是基于html的dom元素属性的,适合前后联调。
posted @   danielzzz  阅读(122)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示