网页静态化解决方案-FreeMarker

概述

  • FreeMarker 是一款模板引擎:即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库(Library),是一款程序员可以嵌入他们所开发产品的组件。
  • 作用:与缓存技术一样,网页静态化技术减轻了数据库访问压力,但应用场景不同。
    • 缓存:适合较小规模数据的场景
    • 网页静态化:适合大规模数据不经常变化的场景,而且有利于SEO(Search Engine Optimization)
  • 应用:网页静态化解决方案在实际开发中运用比较多。例如新闻网站,门户网站中的新闻频道或者是文章类的频道。
  • 注意:高性能web服务器Nginx适合部署此类纯静态化网页。Nginx可承载五万的并发量,而Tomcat只有几百。

快速入门

  1. 引入freemarker依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.23</version>
    </dependency>
  2. 创建模板

  • 模板文件中四种元素

    1. 文本,直接输出的部分
    2. 注释,即<#-- ... -->格式不会输出
    3. 插值(Interpolation):即${...}部分,将使用数据模型中的部分替代输出
    4. FTL指令:FreeMarker指令,和HTML标记类似,名字前加#予以区分,不会输出。
  • 创建模板文件test.ftl

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <html>
    <head>
    <meta charset="utf-8">
    <title>FreeMarker快速入门</title>
    </head>
    <body>
    <#-- 我是一个注释,我不会输出 -->
    ${name},你好。${message}
    </body>
    </html>
  1. 生成文件
  • 创建Test类main方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    //1.创建配置类
    Configuration configuration=new Configuration(Configuration.getVersion());
    //2.设置模板所在的目录
    configuration.setDirectoryForTemplateLoading(new File("D:/pinyougou_work/freemarkerDemo/src/main/resources/"));
    //3.设置字符集
    configuration.setDefaultEncoding("utf-8");
    //4.加载模板
    Template template = configuration.getTemplate("test.ftl");
    //5.创建数据模型
    Mapmap=newHashMap();
    map.put("name", "张三");
    map.put("message", "欢迎来到神奇的FreeMarker世界!");
    //6.创建Writer对象
    Writer out =new FileWriter(new File("d:\\test.html"));
    //7.输出
    template.process(map, out);
    //8.关闭Writer对象
    out.close();
  • 执行后,在D盘根目录即可看到生成的test.html,打开:

常用指令

  • assign:插值

    插值结果可以是字符串、数字、日期值、布尔值。

    当插值结果为字符串时,直接输出表达式结果

    当插值结果为数字时,将结果转化为文本输出,可以使用内建字符串函数格式化插值

    当插值结果为日期时,将结果转化为文本输出,可以使用内建字符串函数格式化插值

    当插值结果为布尔值时,将结果转化为文本输出,可以使用内建字符串函数格式化插值

    1
    2
    <#assign prchen="hello"/> 
    ${prchen}

    输出结果是hello

  • include:引入

    include指令类似于JSP的include指令,用来引入指定的页面,提高代码复用性,格式如下:

    1
    <#include filename [options]>

    其中参数的意义:

    filename:该参数指定被包含的模板文件
    options:该参数可以省略,指定包含时的选项,包含encoding和parse两个选项,其中encoding指定包含页面时所用的解码集,而parse指定被包含文件是否作为FTL文件来解析,如果省略了parse选项值,则该选项默认是true。

  • if:判断

    判断流程分支指令,和Java语言中if判断类似,格式如下

    1
    2
    3
    4
    5
    <#if condition1>... 
    <#elseif condition2>...
    <#elseif condition3>...
    <#else> ...
    </#if>
  • list:遍历
    例:遍历 Student 数据模型中学生信息的三种方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <body>
    遍历数据模型中的list学生信息(数据模型中的名称为stus)
    <table>
    <tr>
    <td>序号</td>
    <td>姓名</td>
    <td>年龄</td>
    <td>金额</td>
    <#--<td>出生日期</td>-->
    </tr>
    <#list stus as stu>
    <tr>
    <td>${stu_index+1}</td>
    <td>${stu.name}</td>
    <td>${stu.age}</td>
    <td>${stu.money}</td>
    <#--<td>${stu.birthday}</td>-->
    </tr>
    </#list>
    </table>
    <br/>
    遍历数据模型中的stuMap(map数据),
    <br/>
    第一种方法:在中括号中填写map的key<br/>
    姓名:${stuMap['stu1'].name}<br/>
    年龄:${stuMap['stu1'].age}<br/>
    第二种方法:在map后面直接加"点key"<br/>
    姓名:${stuMap.stu1.name}<br/>
    年龄:${stuMap.stu1.age}<br/>
    第三种方法:遍历map中的key。stuMap?keys就是key列表(是一个list)
    <br/>
    <#list stuMap?keys as k>
    ${k}<br/>
    姓名:${stuMap[k].name}<br/>
    年龄:${stuMap[k].age}<br/>
    </#list>
    </body>

内建函数

  • 格式:变量+?+函数名称

  • 获取集合大小:size

    1
    共 ${goodsList?size} 条记录
  • 转换JSON字符串为对象:eval

    1
    2
    3
    <#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
    <#assign data=text?eval />
    开户行:${data.bank} 账号:${data.account}
  • 日期格式化:date,time,datetime,string("pattern")

    1
    map.put("today", new Date());
    1
    2
    3
    4
    <!--当前日期--> ${today?date} <br>
    <!--当前时间--> ${today?time} <br>
    <!--当前日期+时间--> ${today?datetime} <br>
    <!--日期格式化--> ${today?string("yyyy年MM月")}
  • 数字转换为字符串:c

    1
    <!--累计积分--> ${point?c}
  • 判断变量是否存在:??
    用法为:variable??,如果该变量存在,返回 true,否则返回 false

    1
    2
    3
    4
    5
    <#if aaa??>
    aaa 变量存在
    <#else>
    aaa 变量不存在
    </#if>
  • 缺失变量默认值:!
    可以使用!对 null 值做转换处理,在模板文件中加入${aaa!'aaa未被赋值'},则在代码中不对 aaa 赋值,也不会报错 ,当 aaa 为 null 则返回!后边的内容”aaa未被赋值”

逻辑运算符

  • 逻辑与:&&
  • 逻辑或:||
  • 逻辑非:!
  • 注意:逻辑运算符只能作用于布尔值,否则将产生错误

比较运算符

  1. =或者==:判断两个值是否相等.
  2. !=:判断两个值是否不等.
  3. >或者 gt:判断左边值是否大于右边值
  4. >=或者 gte:判断左边值是否大于等于右边值
  5. <或者 lt:判断左边值是否小于右边值
  6. <=或者 lte:判断左边值是否小于等于右边值
  • 注意:=!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且 FreeMarker 是精确比较,”x”,”x “,”X”是不等的。其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为 FreeMarker 会把>解释成 FTL 标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)>

扫一扫,关注我的微信公众号↓

0%