07-freemarker概述和入门

打印 上一主题 下一主题

主题 547|帖子 547|积分 1641

一、freemarker介绍


  • FreeMarker 是一款 模板引擎

    • 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件

  • 模板编写为FreeMarker Template Language(FTL)

    • 它是简单的,专用的语言,不是像PHP那样成熟的变成语言。那就意味着要准备数据在在真实编程语言中来显示,比如数据库查询和业务运算,之后模板显示以及准备好的数据。在模板中,可以更加专注于如何展现数据,而在模板之外可以专注于要展示什么数据


二、freemarker环境搭建&&快速入门

需要创建Spring Boot + Freemarker 工程用于测试模板
2.1、创建测试工程


  • 创建一个freemark-demo的测试工程用于freemarker的功能测试与模板测试
  • POM文件如下所示

      1. <?xml version="1.0" encoding="UTF-8"?>
      2. <project xmlns="http://maven.apache.org/POM/4.0.0"
      3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      5.     <modelVersion>4.0.0</modelVersion>
      6.     <groupId>com.coolman</groupId>
      7.     <artifactId>freemarker-demo</artifactId>
      8.     <version>1.0-SNAPSHOT</version>
      9.     <properties>
      10.         <maven.compiler.source>8</maven.compiler.source>
      11.         <maven.compiler.target>8</maven.compiler.target>
      12.     </properties>
      13.     <dependencies>
      14.         <dependency>
      15.             <groupId>org.springframework.boot</groupId>
      16.             <artifactId>spring-boot-starter-web</artifactId>
      17.         </dependency>
      18.         
      19.         <dependency>
      20.             <groupId>org.springframework.boot</groupId>
      21.             <artifactId>spring-boot-starter-freemarker</artifactId>
      22.         </dependency>
      23.         
      24.         <dependency>
      25.             <groupId>org.projectlombok</groupId>
      26.             <artifactId>lombok</artifactId>
      27.         </dependency>
      28.     </dependencies>
      29. </project>
      复制代码

2.2、配置文件


  • application.yml文件如下所示

      1. server:
      2.   port: 9527
      3. spring:
      4.   application:
      5.     name: freemarker-demo # 指定服务名
      6.   freemarker:
      7.     cache: false  # 关闭缓存,方便测试
      8.     settings:
      9.       template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试
      10.     suffix: .ftl               #指定Freemarker模板文件的后缀名
      11.     template-loader-path: classpath:/templates  #指定模板文件存放的位置
      复制代码

2.3、创建启动类


  • 启动类如下所示

      1. package com.coolman.freemarker;
      2. import org.springframework.boot.SpringApplication;
      3. import org.springframework.boot.autoconfigure.SpringBootApplication;
      4. @SpringBootApplication
      5. public class FreemarkerApplication {
      6.     public static void main(String[] args) {
      7.         SpringApplication.run(FreemarkerApplication.class, args);
      8.     }
      9. }
      复制代码

2.4、创建模型类


  • 在freemarker的测试工程下创建模型类型用于测试

      1. package com.coolman.freemarker.model;
      2. import lombok.AllArgsConstructor;
      3. import lombok.Data;
      4. import lombok.NoArgsConstructor;
      5. @Data
      6. @AllArgsConstructor
      7. @NoArgsConstructor
      8. public class Person {
      9.     private String name;
      10.     private Integer age;
      11. }
      复制代码

2.5、创建模板


  • 在resources下创建templates,并创建模板文件freemarker.ftl文件(模板中的插值表达式最终会被freemarker替换成具体的数据)

    • 编写一个简单的HTML模板
      1. <!DOCTYPE html>
      2. <html>
      3. <head>
      4.     <meta charset="utf-8">
      5.     <title>Hello Freemarker!</title>
      6. </head>
      7. <body>
      8. <b>普通文本 String 展示:</b>

      9. Welcome to SuperCoolMan's home !!
      10. I’m 99 years old this year !!
      11. <hr>
      12. <hr>
      13. </body>
      14. </html>
      复制代码

2.6、创建测试类并测试


  • 创建Controller类,添加数据,最后返回模板文件

    • 测试1:

        1. package com.coolman.freemarker.controller;
        2. import freemarker.template.Configuration;
        3. import freemarker.template.Template;
        4. import freemarker.template.TemplateException;
        5. import org.springframework.beans.factory.annotation.Autowired;
        6. import org.springframework.web.bind.annotation.GetMapping;
        7. import org.springframework.web.bind.annotation.RequestMapping;
        8. import org.springframework.web.bind.annotation.RestController;
        9. import java.io.FileWriter;
        10. import java.io.IOException;
        11. import java.util.HashMap;
        12. @RestController
        13. @RequestMapping("/freemarker")
        14. public class FreemarkerController {
        15.     // 引入freemarker.template包下的Configuration类,用来获取指定的模板对象
        16.     @Autowired
        17.     private Configuration configuration;
        18.     /**
        19.      * 通过模板文件,生成html文件
        20.      */
        21.     @GetMapping("/test")
        22.     public String getHtml() {
        23.         try {
        24.             // 使用Configuration的getTemplate方法,指定模板文件,获取模板对象
        25.             Template template = configuration.getTemplate("HelloFreemarker.ftl");
        26.             // 绑定数据
        27.             // 数据1:
        28.             HashMap<String, Object> map = new HashMap<>();
        29.             map.put("name", "SuperCoolMan");
        30.             map.put("age", 99);
        31.             FileWriter fileWriter = new FileWriter("E:\\系统默认\\桌面\\news-init\\freemarker-demo\\src\\main\\resources\\testHtml\\HelloFreemarker.html");
        32.             template.process(map, fileWriter);
        33.             return "SUCCESS!";
        34.         } catch (IOException | TemplateException e) {
        35.             e.printStackTrace();
        36.         }
        37.         return "ERROR!";
        38.     }
        39. }
        复制代码
      • 浏览器打开生成的静态文件



  • 修改Controller中的方法,添加Person对象数据

      1. package com.coolman.freemarker.controller;
      2. import com.coolman.freemarker.model.Person;
      3. import freemarker.template.Configuration;
      4. import freemarker.template.Template;
      5. import freemarker.template.TemplateException;
      6. import org.springframework.beans.factory.annotation.Autowired;
      7. import org.springframework.web.bind.annotation.GetMapping;
      8. import org.springframework.web.bind.annotation.RequestMapping;
      9. import org.springframework.web.bind.annotation.RestController;
      10. import java.io.FileWriter;
      11. import java.io.IOException;
      12. import java.util.HashMap;
      13. @RestController
      14. @RequestMapping("/freemarker")
      15. public class FreemarkerController {
      16.     // 引入freemarker.template包下的Configuration类,用来获取指定的模板对象
      17.     @Autowired
      18.     private Configuration configuration;
      19.     /**
      20.      * 通过模板文件,生成html文件
      21.      */
      22.     @GetMapping("/test")
      23.     public String getHtml() {
      24.         try {
      25.             // 使用Configuration的getTemplate方法,指定模板文件,获取模板对象
      26.             Template template = configuration.getTemplate("HelloFreemarker.ftl");
      27.             // 绑定数据
      28.             // 数据1:
      29.             HashMap<String, Object> map = new HashMap<>();
      30.             map.put("name", "SuperCoolMan");
      31.             map.put("age", 99);
      32.             // 数据2:
      33.             map.put("person", new Person("超级猛男", 18));
      34.             FileWriter fileWriter = new FileWriter("E:\\系统默认\\桌面\\news-init\\freemarker-demo\\src\\main\\resources\\testHtml\\HelloFreemarker.html");
      35.             template.process(map, fileWriter);
      36.             return "SUCCESS!";
      37.         } catch (IOException | TemplateException e) {
      38.             e.printStackTrace();
      39.         }
      40.         return "ERROR!";
      41.     }
      42. }
      复制代码
    • 修改模板

        1. <!DOCTYPE html>
        2. <html>
        3. <head>
        4.     <meta charset="utf-8">
        5.     <title>Hello Freemarker!</title>
        6. </head>
        7. <body>
        8. <b>普通文本 String 展示:</b>

        9. Welcome to ${name}'s home !!
        10. I’m ${age} years old this year !!
        11. <hr>
        12. <b>对象Person中的数据展示:</b><br/>
        13. 姓名:${person.name}<br/>
        14. 年龄:${person.age}
        15. <hr>
        16. </body>
        17. </html>
        复制代码

    • 浏览器打开生成的静态文件


2.7、总结



三、freemarker语法指令

3.1、基础语法

3.1.1、注释


  • 注释,即,介于其之间的内容会被freemarker忽略

      1. [/code]
      2. [/list]
      3. [/list][size=4]3.1.2、插值[/size]
      4. [list]
      5. [*]插值(Interpolation):即${<#if >...</#if>}部分,freemarker会用真实的值代替${}(PS:如果返回的数据中没有该真实值,freemarker服务会直接报错)
      6. [list]
      7. [*][code]Welcome to ${name}'s home
      复制代码

3.1.3、FTL指令


  • FTL指令:和HTML标记类似,名字前加#予以区分,Freemarker会解析标签中的表达式或逻辑

      1. <# > FTL指令 </#>
      复制代码

3.1.4、文本


  • 文本,仅文本信息,这些不是freemarker的注释、插值、FTL指令的内容会被freemarker忽略解析,直接输出内容

      1. <#--freemarker中的普通文本-->
      2. 我是一个普通的文本
      复制代码

3.2、集合指令(List、Map)

接下来的测试,只截取部分代码,直接在原代码的基础上增加即可


  • 为了Controller尽可能简略,创建一个getData方法,返回一个Map集合,Controller方法直接调用这个getData生成测试数据即可

      1.     private Map<String, Object> getData() {
      2.         HashMap<String, Object> map = new HashMap<>();
      3.         // String类型:
      4.         map.put("name", "SuperCoolMan");
      5.         map.put("age", 99);
      6.         // Person类型:
      7.         map.put("person", new Person("超级猛男", 18));
      8.         
      9.         //
      10.         return map;
      11.     }
      复制代码

3.2.1、List集合


  • Controller

      1. // List集合类型
      2.         ArrayList<Person> list = new ArrayList<>();
      3.         list.add(new Person("瞳夕", 18));
      4.         list.add(new Person("二呆", 18));
      5.         list.add(new Person("嘿嘿", 18));
      6.         map.put("wifeList", list);
      复制代码

  • 模板

      1. <b>List类型中的数据展示:</b><br/>
      2.     <#list wifeList as wife>
      3.         序号:${wife_index + 1} <br/>   <#--freemarker中FTL指令自带的序号属性,默认从0开始-->
      4.         姓名:${wife.name} <br/>
      5.         年龄:${wife.age}  <br/><br/>
      6.     </#list>
      7. <hr>
      复制代码

  • 最终效果



3.2.2、Map集合


  • Controller

      1. // Map集合类型
      2.         HashMap<String, Object> anOtherMap = new HashMap<>();
      3.         anOtherMap.put("smallWife1", new Person("莫妮卡", 18));
      4.         anOtherMap.put("smallWife2", new Person("玛丽莲梦露", 18));
      5.         map.put("smallWife", anOtherMap);
      复制代码

  • 模板

      1. <b>Map + Person 类型中的数据展示:</b><br/>
      2.     <b>方式一:通过map['keyname'].property 输出对应信息:</b><br/>
      3.         性别:${wifeMap['smallWife1'].name} <br/>
      4.         年龄:${wifeMap['smallWife1'].age} <br/>
      5.     <b>方式二:通过map.keyname.property 输出对应信息:</b><br/>
      6.         性别:${wifeMap.smallWife2.name} <br/>
      7.         年龄:${wifeMap.smallWife2.age} <br/>
      8. <hr>
      复制代码

  • 最终效果



  • 遍历Map集合

    • 模板

        1. <b>遍历Map中多个Person信息:</b><br/>
        2.     <#list wifeMap?keys as key>
        3.         序号:${key_index} <br/>
        4.         性别:${key.name} <br/>
        5.         年龄:${key.age} <br/><br/>
        6.     </#list>
        7. <hr>
        复制代码

    • 最终效果




3.3、if指令


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

    • 指令格式

        1. <#if >...</#if>
        复制代码


  • Controller

      1. // if test
      2. map.put("score", 88);
      复制代码

  • 模板

      1. <b>if指令测试:</b><br/>
      2.     <#if (score > 90)>
      3.         继续努力
      4.     <#elseif (score > 80)>
      5.         面包总会有的
      6.     <#else>
      7.         革命尚未成功,同志仍需努力
      8.     </#if>
      9. <hr>
      复制代码

  • 最终效果



3.4、空值处理

3.4.1、判断某变量是否存在


  • 语法格式

    • variable??

  • 如果该变量存在,返回true,否则返回false
  • 如下例所示

      1.         <#if >...</#if><#if >...</#if>   
      复制代码

3.4.2、缺失变量默认值


  • 使用!要指定一个默认值,当变量为空的时候显示默认值

    • 例:${name!'默认值'}表示如果name为空,显示默认值

  • 如果是嵌套对象则建议使用()括起来

    • 例:${(stu.bestFriend.name)!"默认值"}表示如果stu或者bestFriend或者name为空默认显示默认值

3.5、内建函数

3.5.1、获取集合大小


  • 模板中直接取值

    • ${集合名?size}

3.5.2、日期格式化


  • 后端返回一个Date对象,模板要取值,则如下所示

    • map.put("today",new Date())
    • 显示年月日

      • ${today?date}

    • 显示时分秒

      • ${today?time}

    • 显示日期+时间

      • ${today?datetime}

    • 自定义格式化

      • ${today?string("yyyy年MM月")}


3.5.3、内建函数c(数字格式化)


  • 后端返回一串数字,模板可以对其进行格式化,如下所示

    • map.put("point", 102920122);

  • point是数字型,使用${point}会显示这个数字的值,每三位使用逗号隔开
  • 如果不像显示为每三位分隔的数字,可以使用c函数将数字转成字符串输出
  • 指令格式如下所示

    • ${point?c}


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

怀念夏天

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表