FreeMarker的使用

本文深入介绍了FreeMarker模板引擎的使用,包括前期准备、模板开发、单个属性和对象展示、If条件判断、List循环、Include文件包含以及其他配置。通过Java代码示例展示了如何填充数据并输出到控制台,同时提供了模板文件的创建和配置,以及自动生成Java类文件的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二八佳人体似酥,腰间仗剑斩愚夫。虽然不见人头落,暗里教君骨髓枯。

一. FreeMarker 的介绍

FreeMarker 的官方网址: http://freemarker.foofun.cn/index.html

解释的很详细,直接看官方网址就可以了。

二. Java 使用FreeMarker

二.一 前期准备

创建一个 Maven 项目, 在 pom.xml 中添加 依赖

 <!--添加FreeMarker的依赖 ,版本是 2.3.29-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.29</version>
        </dependency>
        <!--测试junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

image-20210729200324820

resources 目录下的 freemark 文件夹对应的目录是: D:\learncode\Template\FreeMark\Basic\src\main\resources\freemark

二.二 模板开发

这儿不与 Web 进行关联,不采用页面展示, 采用控制台输出。

二.二.一 单个属性展示

二.二.一.一 单个属性模板 FTL

创建 hello.ftl 文件

<html>
<head>
    <title>${title}</title>
</head>
<body>
    Hello ${info}
</body>
</html>

有两个属性 title 和 info 进行填充。

二.二.一.二 单个属性开发
@Test
    public void fillBaseTest() throws Exception{
        //1. 指定配置,对应着哪一个版本
         Configuration configuration=new Configuration(
                 Configuration.VERSION_2_3_29
         );
         //设置目录
         configuration.setDirectoryForTemplateLoading(
                 new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark")
         );
         //指定编码
        configuration.setDefaultEncoding("utf-8");
        //指定异常处理器
        configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

        //开始创建数据
        Map<String,Object> root=new HashMap<>();
        root.put("title","Hello Freemark");
        root.put("info","两个蝴蝶飞");
        //找到要设置的,对应的模板
        Template template=configuration.getTemplate("hello.ftl","utf-8");
        //写出到控制台
        Writer out=new OutputStreamWriter(System.out);
        //进行填充 数据和信息。
        template.process(root,out);
    }

image-20210729200933252

二.二.二 单个对象展示

二.二.二.一 单个对象模板 FTL

创建 info.ftl 文件

<html>
<head>
    <title>Welcome ${web} </title>
</head>
<body>
<h1>Welcome ${user}!</h1>
<p>Our latest product:
    <a href="${info.url}">${info.name}</a>!
</body>
</html>

web, user 属性是单个属性, info.url, info.name 可以知道, info 是个对象。

二.二.二.二 单个对象开发
@Test
    public void fillInfoTest() throws Exception{
        //1. 设置相应的 Configuration
        Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
        //2. 设置基本的目录
        configuration.setDirectoryForTemplateLoading(
                new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark")
        );
        //3. 设置编码
        configuration.setDefaultEncoding("utf-8");
        //设置错误处理器
        configuration.setTemplateExceptionHandler(
                TemplateExceptionHandler.RETHROW_HANDLER
        );

        //4. 构建数据
        Map<String,Object> root=new HashMap<>();
        root.put("web","百度");
        root.put("user","两个蝴蝶飞");
        Map<String,Object> info=new HashMap<>();
        info.put("url","www.yueshushu.top");
        info.put("name","百度");
        root.put("info",info);

        //5. 获取对应的模板
        Template template=configuration.getTemplate("info.ftl");
        //6.构建输出对象
        Writer out=new OutputStreamWriter(System.out);
        //7. 调用 process 方法,进行填充数据
        template.process(root,out);
    }

image-20210729201219499

二.二.三 If 展示

二.二.三.一 IF模板 FTL

创建 if.ftl 文件

<html>
<head>
    <title>Welcome ${web} </title>
</head>
<body>
<!--单个if展示-->
<h1>Welcome ${user}! <#if user='yjl'>,领导牛逼</#if></h1>
<p>Our latest product:
    <a href="${info.url}">${info.name}</a>!
<h2>性别是:</h2>
<!--if else 展示-->
<#if sex=='男'>
     男
<#else></#if>
<h2>成绩是:</h2>
<!--if elseif else-->
<#if score &gt;90 ><#elseif score &gt;80><#elseif score &gt;70><#elseif score &gt;60><#else></#if>>
</body>
</html>
二.二.三.二 IF 开发
@Test
    public void ifFillTest() throws Exception{
        //1. 通过版本,获取相关的配置
        Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
        //2. 设置扫描的包的基本路径
        configuration.setDirectoryForTemplateLoading(
                new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark")
        );
        //3. 设置基本路径
        configuration.setDefaultEncoding("utf-8");

        //4. 设置数据
        Map<String,Object> root=new HashMap<>();
        root.put("web","IF验证");
        root.put("user","yjl2");
        Map<String,Object> info=new HashMap<>();
        info.put("url","www.baidu.com");
        info.put("name","百度");
        root.put("info",info);
        root.put("sex","女");
        root.put("score",75);
        //5. 获取对应的模板文件
        Template template=configuration.getTemplate("if.ftl");
        //6. 输出到控制台
        Writer out=new OutputStreamWriter(System.out);
        //7. 通过 process() 方法进行填充数据和输出信息对象.
        template.process(root,out);
    }

image-20210729201745622

二.二.四 list 循环开发

二.二.四.一 list循环FTL

创建 list.ftl 文件

<html>
<head>
    <title>Welcome ${web} </title>
</head>
<body>
<h2> list 的相关展示</h2>
<ul>
<#list hobbys as hobby>
    <li>${hobby}</li>
</#list>
</ul>

<h2> list展示一起,</h2>
<#list hobbys>
    <ul>
        <#-- 用items 表示内部的元素, items -->
        <#items as hobby>
            <li>${hobby}
        </#items>
    </ul>
</#list>
<h2>分隔符展示</h2>
<p> hobbys: <#list hobbys as hobby>${hobby}<#sep>, </#list> </p>
<h2>展示表格的数据信息</h2>
<table>
    <th>
        <td>id编号</td>
        <td>名称</td>
        <td>年龄</td>
        <td>性别</td>
        <td>描述</td>
    </th>
    <#if uers??>
       <#list users as u>
           <tr>
               <td>${u.id}</td>
               <td>${u.name}</td>
               <td>${u.age}</td>
               <td><#if u.sex==1>男<#else></#if></td>
               <td>${u.description}</td>
           </tr>
       </#list>
        <#-- 如果为空的话, #else 表示为空的意义-->
        <#else>
        <tr>
            没有数据
        </tr>
        </#if>
</table>
</body>
</html>
二.二.四.二 List循环开发

对应的 User.java 对象

package com.zk.template.freemark.pojo;
import lombok.Data;
@Data
public class User {
    private Integer id;
    private String name;
    private Integer sex;
    private Integer age;
    private String description;
}

 @Test
    public void listFillTest2() throws Exception{
        Configuration configuration=new Configuration(
                Configuration.VERSION_2_3_29
        );
        configuration.setDirectoryForTemplateLoading(
                new File(
                        "D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark"
                )
        );
        configuration.setDefaultEncoding("utf-8");

        //4. 设置数据
        Map<String,Object> root=new HashMap<>();
        root.put("web","List循环");
        List<String> hobbys=new ArrayList<>();
        hobbys.add("看书");
        hobbys.add("打游戏");
        hobbys.add("编程");
        root.put("hobbys",hobbys);
        //获取集合对象
        List<User> userList=getUserList();
        root.put("users",userList);
        //5. 获取模板
        Template template=configuration.getTemplate("list.ftl");
        //输出信息
        Writer out=new OutputStreamWriter(System.out);
        //7. 进行填充数据
        template.process(root,out);
    }

    private List<User> getUserList() {
        List<User> userList=new ArrayList<>();
        for(int i=1;i<=10;i++){
            User user=new User();
            user.setId(i);
            user.setName("蝴蝶"+i);
            user.setAge(i*3+1);
            user.setSex(i%2);
            user.setDescription("一个简单的描述");
            userList.add(user);
        }
        return userList;
    }

image-20210729202345801

二.二.五 include 包含文件

二.二.五.一 include 文件 FTL

创建 foot.ftl

<hr>
<i>
    Copyright (c) 2000 <a href="top.yueshushu.com">yueshushu_top</a>,
    <br>
</i>

创建 footinclude.ftl

<html>
<head>
    <title>Include page</title>
</head>
<body>
<h1>Include page</h1>
<p>
    <#-- 放置进去, #include 填充进去。 #include 填充进去。-->
    <#include "foot.ftl">
</body>
</html>
二.二.五.二 include 开发
 @Test
    public void includeFillTest() throws Exception{
        //1. 通过版本,获取相关的配置
        Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
        //2. 设置扫描的包的基本路径
        configuration.setDirectoryForTemplateLoading(
                new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark")
        );
        //3. 设置基本路径
        configuration.setDefaultEncoding("utf-8");
        //5. 获取对应的模板文件
        Template template=configuration.getTemplate("footinclude.ftl");
        //6. 输出到控制台
        Writer out=new OutputStreamWriter(System.out);
        //7. 通过 process() 方法进行填充数据和输出信息对象.
        template.process(null,out);
    }

在这里插入图片描述

二.二.六 其他配置

二.二.六.一 其他配置FTL

创建 other.ftl

  1. 字符串嵌套输出
<#--字符串嵌套输出-->
<h3>字符串嵌套输出</h3>
${"hello ${name}"}
  1. 定义变量

    <h3>定义变量输出</h3>
    <#assign number1 = 10>
    <#assign number2 = 5>
    
  2. 算术运算符

    <h3>定义变量输出</h3>
    <#assign number1 = 10>
    <#assign number2 = 5>
    <#-- 支持"+"、"-"、"*"、"/"、"%"运算符 -->
    "+" : ${number1 + number2}
    "-" : ${number1 - number2}
    "*" : ${number1 * number2}
    "/" : ${number1 / number2}
    "%" : ${number1 % number2}
    
  3. 内建函数

    <h3>内建函数</h3>
    第一个字母大写: ${str?cap_first}
    所有字母小写: ${str?lower_case}
    所有字母大写: ${str?upper_case}
    
  4. 将数据取整

    <h3>将数据取整</h3>
    <#assign floatData = 12.34>
    数值取整数:${floatData?int}
    
  5. 获取集合的长度

<h3>获取集合的长度:</h3>
获取集合的长度:${users?size}
  1. 日期进行格式化

    <h3>日期进行格式化</h3>
    时间格式化:${dateTime?string("yyyy-MM-dd")}
    
  2. 循环遍历 map

<#--循环遍历map-->
      Map集合:
      <#assign mapData={"name":"程序员", "salary":15000}>
      直接通过Key获取 Value值:${mapData["name"]}
      通过Key遍历Map:
      <#list mapData?keys as key>
          Key: ${key} - Value: ${mapData[key]}
      </#list>
      通过Value遍历Map:
      <#list mapData?values as value>
          Value: ${value}
      </#list>
  整体编写:
      <html>
      <head>
          <title>这是放置freemark的其他的相关的用法</title>
      </head>
      <body>
      <#--字符串嵌套输出-->
      <h3>字符串嵌套输出</h3>
      ${"hello ${name}"}
      <h3>定义变量输出</h3>
      <#assign number1 = 10>
      <#assign number2 = 5>
      <#-- 支持"+"、"-"、"*"、"/"、"%"运算符 -->
      "+" : ${number1 + number2}
      "-" : ${number1 - number2}
      "*" : ${number1 * number2}
      "/" : ${number1 / number2}
      "%" : ${number1 % number2}
      <h3>内建函数</h3>
      第一个字母大写: ${str?cap_first}
      所有字母小写: ${str?lower_case}
      所有字母大写: ${str?upper_case}
      <h3>将数据取整</h3>
      <#assign floatData = 12.34>
      数值取整数:${floatData?int}
      <h3>获取集合的长度:</h3>
      获取集合的长度:${users?size}
      <h3>日期进行格式化</h3>
      时间格式化:${dateTime?string("yyyy-MM-dd")}
      <#--循环遍历map-->
      Map集合:
      <#assign mapData={"name":"程序员", "salary":10000}>
      直接通过Key获取 Value值:${mapData["name"]}
      通过Key遍历Map:
      <#list mapData?keys as key>
          Key: ${key} - Value: ${mapData[key]}
      </#list>
      通过Value遍历Map:
      <#list mapData?values as value>
          Value: ${value}
      </#list>
      </body>
      </html>
二.二.六.二 其他配置开发
      @Test
          public void otherFill() throws Exception{
              //1. 创建 Configuration 对象
              Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
              //2. 设置基本的目录信息。
              configuration.setDirectoryForTemplateLoading(new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark"
                      ));
              //3. 设置编码等格式
              configuration.setDefaultEncoding("utf-8");
              //4. 设置要添加的数据信息
              Map<String,Object> root=new HashMap<>();
              root.put("name","两个蝴蝶飞");
              root.put("str","Two Butterfly");
              List<User> userList=getUserList();
              root.put("users",userList);
              root.put("dateTime",new Date());
      
              //5. 获取对应的模板
              Template template=configuration.getTemplate("other.ftl","utf-8");
              //6. 设置输出对象
              Writer out=new OutputStreamWriter(System.out);
              //7. 调用 template的 process 方法,进行填充
              template.process(root,out);
          }
          private List<User> getUserList() {
              List<User> userList=new ArrayList<>();
              for(int i=1;i<=10;i++){
                  User user=new User();
                  user.setId(i);
                  user.setName("蝴蝶"+i);
                  user.setAge(i*3+1);
                  user.setSex(i%2);
                  user.setDescription("一个简单的描述");
                  userList.add(user);
              }
              return userList;
          }

image-20210729203432172

三. 使用 FreeMarker 配置模板文件

可以使用 FreeMarker的配置文件, 通过往模板里面填充属性,来创建特定的文件。

如生成一个基本的 Main 类

image-20210729203645084

三.一 模板 FTL

package ${packageName};
/**
  @author: ${author}
  @Date: ${createDate?string("yyyy-MM-dd hh:mm:ss")}
  @Description: ${classDescription}
*/
public class ${className}{
    /**
        功能描述: ${mainMethodDesc!TODO}
    */
    public static void main(String []args){
        System.out.println("${info}");
    }
}

三.二 模板类创建

public class CodeAuto {
    public static String FTLTEMPLATE="src/main/java/com/zk/template/freemark/code/";
    public static String CODELOCATION="src/main/java/com/zk/template/freemark/code/";
    @Test
    public void codeGenerate() throws Exception{
        Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
        configuration.setDirectoryForTemplateLoading(new File(FTLTEMPLATE));
        configuration.setDefaultEncoding("utf-8");
        //填充数据
        Map root=getMainMap();
        //获取对应的模板
        Template template=configuration.getTemplate("main.ftl","utf-8");
        //获取对应的输出流
        Writer out=new BufferedWriter(
                new OutputStreamWriter(
                    new FileOutputStream(
                            CODELOCATION+"FreeMain.java"
                    )
                )
        );
        template.process(root,out);
        System.out.println(">>>>>>创建模板类成功");
    }
    private Map<String,Object> getMainMap() {
        Map<String,Object> root=new HashMap<>();
        root.put("packageName","com.zk.template.freemark.code");
        root.put("author","TwoButterfly");
        root.put("createDate",new Date());
        root.put("classDescription","一个测试Freemark 自动生成类");
        root.put("className","FreeMain");
        root.put("mainMethodDesc","一个普通的测试方法");
        root.put("info","Freemark 创建类生成信息");
        return root;
    }
}

image-20210729203921800

image-20210729203942746

生成的模板文件类:

image-20210729204017610

本章节的代码放置在 github 上:

https://github.com/yuejianli/springboot/tree/develop/FreeMark

谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

两个蝴蝶飞

你的鼓励,是老蝴蝶更努力写作的

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

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

打赏作者

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

抵扣说明:

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

余额充值