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 @ 2021-10-26 13:26  danielzzz  阅读(143)  评论(0)    收藏  举报