整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Spring Boot使用freemarker并且生成静态html页面

pring Boot使用freemarker并且生成静态html页面

之前我介绍了在spring boot中使用thymeleaf模板,这次我会给大家介绍在spring boot中使用freemarker模板技术,同时利用freemarker生成静态html页面。生成静态html页面就能实现网站的静态化进而提高网站的访问速度以及提高SEO能力。

首先在pom.xml中添加依赖

添加依赖

<dependency>
 <groupId>org.freemarker</groupId>
 <artifactId>freemarker</artifactId>
 <version>2.3.23</version>
 </dependency>

application配置

在application.properties中添加freemarker的配置参数

##freemarker
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.enabled=true
spring.freemarker.suffix=.ftl
spring.freemarker.template-loader-path=classpath:/templates

Controller和ftl模板

下一步我们就建一个基础Controller类和配套的ftl模板

Controller类

package com.hw.myp2c.common.controller;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.io.*;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("")
public class MainController {
 @GetMapping
 public String main(Model model){
 String w="Welcome FreeMarker!";
 Map root = new HashMap();
 root.put("w",w);
 model.addAttribute("w","Welcome FreeMarker!");
 return "test";
 }
}

可以看到很简单,跟之前的thymelefa和jsp的没有区别。

freemarker模板

<html>
<head>
 <title>Welcome!</title>
 <link rel="stylesheet" href="/bootstrap.min.css">
 <script src="/lib/jquery.min.js"></script>
</head>
<body>
<h1>Hello ${w}!</h1>
</body>
</html>

这样之后我们就能完成了基础freemarker的使用,更多的使用参见freemarker官方网站,这里不做过多的描述。

这里我们已经完成了标准的freemarker集成,下面我们将介绍如何利用freemarker生成静态html页面,直接上代码,作为演示我们还是在Controller中完成,在实际应用中我们可以按照自己的实际需要进行封装。

package com.hw.myp2c.common.controller;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.io.*;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("")
public class MainController {
 @Resource
 Configuration cfg;
 @GetMapping
 public String main(Model model){
 String w="Welcome FreeMarker!";
 Map root = new HashMap();
 root.put("w",w);
 freeMarkerContent(root);
 model.addAttribute("w","Welcome FreeMarker!");
 return "test";
 }
 private void freeMarkerContent(Map<String,Object> root){
 try {
 Template temp = cfg.getTemplate("test.ftl");
 //以classpath下面的static目录作为静态页面的存储目录,同时命名生成的静态html文件名称
 String path=this.getClass().getResource("/").toURI().getPath()+"static/test.html";
 Writer file = new FileWriter(new File(path.substring(path.indexOf("/"))));
 temp.process(root, file);
 file.flush();
 file.close();
 } catch (IOException e) {
 e.printStackTrace();
 } catch (TemplateException e) {
 e.printStackTrace();
 } catch (URISyntaxException e) {
 e.printStackTrace();
 }
 }
}

利用freemarker生成静态页面我理解的流程是这样的

1.利用Configuration读取想生成静态页面的模板,这里是test.ftl

2.解析模板文件,并将模板中的${}!包含的参数替换成真实的数据

3.最终将读取了真实数据的模板生成相应的html文件,并写入指定目录

这样我们就完成了spring boot中使用freemarker模板,并且利用freemarker生成静态html文件

击右上方,关注开源中国OSC头条号,获取最新技术资讯

一、前言

上一篇 <从现在开始,试着学会用官方文档去学习一个技术框架> 提倡大家多去从官方文档学习技术,没有讲到具体的实践,本篇就拿一个案例具体的说一说,就是FreeMarker,选择这个框架没什么特别的含义,最近要用,就拿这个做个典型。

二、套路

上篇文章最后说到技术学习没有套路,无招胜有招,无招即是有招,解读一下实际上就是说 本身还是有些招式套路,但是要灵活运用,不要什么都往上套,应该忘掉固有的套路,让其化为你的一种本能,见招拆招。

下面就介绍一种常规学习套路给大家,如下图:

下面就根据上面的套路结合FreeMarker官网溜一遍,来学习FreeMarker,重点在前4部分,后面两部分需要一些积累和经验后才更容易上手,所以本篇不会重点讲

三、实践

3.1 了解框架

首先我们应该了解FreeMarker是用来干什么的,这时候我看打开官网 https://freemarker.apache.org/

上图来自官网首页上方的导航,依次为 Home(主页)Manual(手册)JavaApi(API接口)、Contribute(贡献)、 Report a Bug(反馈BUG)、 Download(下载) , 单词不认识,找工具翻译一下,没有别的办法,上篇也提到了。从字面意思理解可以看出跟我们有关的就是标红的那4个,好的来看看首页的介绍(大部分框架首页都会有简要介绍,说明框架的用途):

这是首页的两段介绍,自行翻译一下,这里就不在翻译了,解读一下,我们从这两段内容中可以得到如下信息:

(1)这是一个Java模板引擎

(2)用模板语言(FTL)编写

(3)基本思想:java或其他编程语言准备数据,FreeMarker显示数据,配合官方给的图,更直观

(4)在模板中,您关注的是如何显示数据,而在模板之外,您关注的是显示什么数据,这也是所有模板引擎解决的核心问题 数据与显示分离

(5)用于MVC模式,有助于分离Java开发人员和web设计人员,设计人员不会在模板中面对复杂的逻辑,并且可以在不需要程序员更改或重新编译代码的情况下更改页面的外观,这里就说明了模板的好处,面试问你,为什么用模板技术啊,结合上面的一点就可以完美回答这个问题了

(6)不依赖Servlet,也就是web环境和非Web环境都可以使用

(7)更多细节内容看 manual (手册)

通过解读官方的文档,我们就可以得到以上7个方面的信息。也就了解了Freemarker的作用、基本思想、好处、应用环境,这些东西,相信在很多FreeMarker的教程中,都不会这么详细,而且上面的信息基本上只要你把英文翻译过来都可以直观看到,我并没有做太多总结性归纳。 这是基本内容,首页还标出了一些特性我们再来看一下

解读一下得到的信息如下

(1)强大的模板语言,支持条件块、迭代、赋值、字符串和算术操作等

(2)零依赖,任何输出格式,可以从任何地方加载模板

(3)支持国际化

(4)支持xml数据模型,也就是可以将xml数据填充到模板上

(5)支持java对象暴露在模板,简单理解模板中可以调用对象的方法

结合上面的基本内容和特性部分的内容,相信大家对freemarker有了较为完整的认识,包括能不能满足自己的一些场景,也会有一些基本的判断,方便技术选型。

3.2 Helloworld

看完基本内容,有了大致了解后,是不是迫不及待想去敲代码试一下,小阶段的输出成果更容易促使学习的动力。看文档首页显然没有告诉我们怎么用,怎么去开始写代码,但提到了更多内容看manual,那我们就点到manual去看一下

从这里我看看到了Getting Started(开始),大部分的官网都会有Getting Started,点进去看一下,这里要多做一件事,写代码肯定要使用freemarler的jar,我们就从download去拿一下,进到download

可以看到,我们可以直接下freemarker.jar、源码,或者通过maven引入,这里大家随意,导入工程,然后回到刚才的地方,看quick start

三块内容

(1)模板 + 数据模型 = 输出

(2)一睹数据模型

(3)一睹模板

分别点进去看一下,可以了解到

(1) 模板有表达式和指令

(2) 数据模型是树形结果

但是我们没有看到代码,只看到一段模板代码和最终的结果输出,这里没有怎么办?我们再扫一眼目录,发现这里还有个Getting Started(一些框架官网没有直接给demo,我们可以去框架托管代码(github、gitee)的地方去找一下,基本上都会有demo)

然后看一下它的分类是 Programmer's Guide(程序员指南),那就应该是这里了,点进去看一下,可以看到,除过最后最后的 Putting all together, 其他部分是使用模板的每一个步骤,分为:创建配置实例 -> 创建数据模型 -> 获取模板 -> 合并数据模型到模板,这也是使用freemaker的基本步骤,分步骤的就不看了,我们直接看最后的Putting all together(所有合到一起的内容)

测试类

public class Test {
 public static void main(String[] args) throws Exception {
 /* ------------------------------------------------------------------------ */
 /* You should do this ONLY ONCE in the whole application life-cycle: */
 /* Create and adjust the configuration singleton */
 Configuration cfg = new Configuration(Configuration.VERSION_2_3_27);
 cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates"));
 cfg.setDefaultEncoding("UTF-8");
 cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
 cfg.setLogTemplateExceptions(false);
 cfg.setWrapUncheckedExceptions(true);
 /* ------------------------------------------------------------------------ */
 /* You usually do these for MULTIPLE TIMES in the application life-cycle: */
 /* Create a data-model */
 Map root = new HashMap();
 root.put("user", "Big Joe");
 Product latest = new Product();
 latest.setUrl("products/greenmouse.html");
 latest.setName("green mouse");
 root.put("latestProduct", latest);
 /* Get the template (uses cache internally) */
 Template temp = cfg.getTemplate("test.ftlh");
 /* Merge data-model with template */
 Writer out = new OutputStreamWriter(System.out);
 temp.process(root, out);
 // Note: Depending on what `out` is, you may need to call `out.close()`.
 // This is usually the case for file output, but not for servlet output.
 }
}

数据模型

/**
 * Product bean; note that it must be a public class!
 */
public class Product {
 private String url;
 private String name;
 // As per the JavaBeans spec., this defines the "url" bean property
 // It must be public!
 public String getUrl() {
 return url;
 }
 public void setUrl(String url) {
 this.url = url;
 }
 // As per the JavaBean spec., this defines the "name" bean property
 // It must be public!
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
}

模板 test.ftlh

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

相信不出意外,复制粘贴到自己的工程里,就可以正常运行了,至此一个helloworld就算OK了,对于代码的含义,可以直接查javaApi, 可以看分步骤的内容有解释。

至此我们对freemarker应该有了更直观的认识和理解,也基本知道了使用的套路

3.3 熟悉配置

为什么要熟悉配置,很多框架的功能支持、 性能调优实际上做的就是配置参数的调整,所以说比较重要,我们来看一下,回到manual首页,找配置相关的字眼,发现

就是它了吧,大概点进去看一下

更多的图就不贴了,总之我们指导这里就是介绍配置属性的地方,详细内容大家自己看一看,这里有一个比较重要的点就是模板加载器,大家自己查阅熟悉一下。

3.4 更多API

熟悉完配置,我们需要了解一些API的使用,这里就不展开了,点到javaApi,自行查阅,这里就不展开说明了。

3.4 表达式、指令

这里的内容在上面的套路图中没标,那个图我表达的是一个通用的套路,这里算套路图中[更多基础API]一种吧。

表达式、指令是对与模板来说的,也就是输出数据的一些命令。浏览文档相关内容找模板、表达式、指令相关的关键字,就可以锁定相关内容主要在

单纯的表达式、指令使用都很简单,这里不多讲了。

3.5 高级用法

所谓高级用法也就是一些提升性能的配置、自定义扩展、一些指令、表达式之类的,这需要大家熟悉基本的使用、配置、api和文档的相关介绍。这里暂不展开,相信有了前面的基础掌握一些技巧和方法,这里来说不是难事。

3.6 原理、源码

这里针对有兴趣,想深入学习的人,写到这是为了保证套路的完整性,这里也不展开,也不是本篇内容的重点。

四、总结

本篇重点是带大家从官网去学习一个技术框架,至少用到一些配置、api知道怎么去查,要学习一个新技术的时候大概需要怎么做,还提了一个基本的学习套路,希望能给需要的人一些帮助。

没看上一篇的建议看一下。

Over。

博客作者:风象南

每日一博栏目,每日为你推荐优秀博主的优质技术文章。同时欢迎用户投稿,文章一旦被官方账号收录,我们会在网站首页等位置进行推荐哦。关注开源中国OSC每日获取优质推送,点击“了解更多”阅读原文章。

↓↓↓

.FreeMarker介绍

FreeMarker是一种模板引擎,通过定义的模板和数据来生成文本(包括但不局限于html,js,java等文本格式),通俗的讲就是先定义一下模板,然后传入不同的数据,动态的生成不同的文本,但它不是面向用户的,而是面向程序员的,可以直接自动的生成代码,减少程序员重复的劳动。FreeMarker最重要的两部分是模板和数据:模板:FreeMarker Template Language,简称FTL,模板文件以ftl为后缀,组成:

  • 文本,包括HTML标签与静态文本等静态内容,会原样输出;

  • 插值:这部分的输出会被计算的数据来替换,使用${}这种语法;

  • 标签:给FreeMarker的指示,可以简单与指令等同,不会打印在内容中;

  • 注释:由<#--和-->表示,不会被freemarker处理 数据结构: 树状结构:HashMap,Scalar,Sequence

2.基本使用

从http://freemarker.org/ 下载FreeMarker的压缩包,将其中的freemarker.jar加到项目的构建路径下从maven仓库中引入maven依赖的jar包,注意两个核心类:

<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.24-atlassian-2</version></dependency>
  • Configuration:读取模板文件

  • Template:模板

 Configuration cfg = new Configuration(Configuration.VERSION_2_3_21); Map<String,String> root= new HashMap<String,String>(); root.put("name", "Java开发日记"); try { cfg.setDirectoryForTemplateLoading(new File("src/ftl")); Template template = cfg.getTemplate("helloworld.ftl"); Writer writer = new FileWriter(new File("src/finish/helloworld.html")); template.process(root, writer); } catch (Exception e) { e.printStackTrace(); }

使用Configuration读取配置文件,使用Map填充数据,给配置文件配置模板文件夹路径,读取模板文件,设置输出文件路径helloworld.html,执行输出文件,执行完之后就会在src目录下的finish文件夹中生成一个helloworld的html文件。模板文件如下:

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>${name}</title></head><body>这是我的第一个程序,${name}</body></html>

3.模板

3.1 数据类型与变量

模板中的数据类型:

  • 标量:字符串,数字,布尔值,日期;

  • 容器:哈希表,序列;

  • 子程序:方法和函数,用户自定义指令; 模板中的变量: 简单变量,局部变量,循环变量,使用赋值指令:assign 示例:

<#assign num=10>${num}<#assign name="Java开发日记">${name}<#assign b=true>${b?c}<#assign map={"name":"张三","age":15}>${map.name}<#assign list = [1,3,5]>${list[2]}

freemarker中使用指令时必须要在指令前面用#(如果是自定义指令用@,后面说),assign指令是用来声明变量的,注意:如果是布尔值,输出时一定要带?c,表示定义的变量是布尔值,不然会报错。

3.2运算符

模板中支持运算符:

  • 算术运算符

  • 比较运算符

  • 逻辑运算符

  • 空值处理运算符

<#assign b=1==2>${b?c}<#assign b=1 gt 2>${b?c}

均输出false,gt表示大于。

3.3 插值

插值是用来给插入具体值然后转换为文本,说白了,插值就是使用${}在那占个坑。使用位置:

  • 文本区(如

    Hello ${name}!

  • 字符串表达式(如<#include "/footer/${company}.html">) 语法:${表达式} 注意:插值表达式的结果必须是字符串,数字或日期类型。

3.4指令

  • 条件指令

<#assign score=50><#if score gt 90>优秀<#elseif score gt 70>良好<#elseif score gt 60>及格<#else>渣渣</#if><#assign level="B"><#switch level> <#case "A"> 优秀 <#break > <#case "B"> 良好 <#break > <#case "C"> soso <#break > <#default> 渣渣</#switch>

需要注意的是switch语句需要有break,不然一直往下执行。

  • 循环指令

<#assign nums=[1,2,3,4,5]><#list nums as num> ${num_index},${num},${num_has_next?c}</#list><#list nums as num> ${num}<#if num_has_next>,</#if></#list>

定义一个集合nums,使用list指令遍历,${别名index}获取遍历的索引值,${别名has_next}判断后面是否还有值,根据这个特性,可以结合if指令拼接不同的值(自动生成mybatis的配置文件时,不同字段最后一个后面不要逗号,用这个特性很好用)。

  • 包含指令

<#include "condition.ftl">从这里开始是自己的内容

使用include引入指令可以引入其它的模板页面。如果页面路径写不好可以用通配符,<#include "*/condition.ftl">

  • 其它 原样输出指令noparse:它里面的内容是原样输出的; 压缩指令compress:压缩所有的空格; 设置指令setting:设置影响FreeMarker的值。

<#noparse> <#assign num=1> ${num}</#noparse><#assign s=" test \n\n"><#compress> ${s} Compress</#compress><#setting locale="hu">${1.2}
  • 自定义指令 可以将模版中重复的内容进行复用 定义: 使用macro指令定义或者使用Java实现。 参数的声明:直接跟在指令名后,可以指定默认值 嵌套内容:使用nested指令 调用: 使用<@指令>来调用(调用freemarker自带的指令用#命令)。

<#macro mydirect name age=20> 你好,${name},你今年${age}</#macro><@mydirect name="Java开发日记" age=1/>

自定义一个指令名为mydirect,它有两个参数name和age,其中age有默认值20,使用自定义指令时用@+自定义指令,同时为参数赋值即可。注意自定义指令是闭口的,不要漏掉最后的斜杠。

3.5 空处理

有时候对象是空的,不进行判断就贸然进行处理会报错,所以要提前进行判空处理。

  • null对象的处理方式:使用!,只会做最后一个属性的判断;

  • 变量不存在的处理方式:使用!或??做判断。

${user.name!}<#if user.name??> 名称存在 <#else> 名称不存在</#if>

我认为是在插值时使用!,在其它指令内使用??。

3.6名称空间

在编写可重复使用的模板时为了避免命名冲突,使用import指令导入命名空间。命名空间有点类似于java的包,即使类名相同,只要位于不同的包下,也是可以的。

test.ftl模板:<#macro mydirective name> 你好,${name}</#macro>namespace.ftl模板<#import "test.ftl" as ns><@ns.mydirective name="Java开发日记" />

在这里我定义两个模板,在namespace.ftl中使用import指令导入test.ftl模板并为它起一个名为ns的命名空间,调用时我使用命令空间调用,即使namespace.ftl模板中有其它同名的也不至于混淆。另外在test.ftl中使用的是自定义指令定义了名为mydirective的指令,并为其制定一个参数name。

3.7函数

FreeMarker中函数有如下几种:

  • 字符串函数;

  • 数字,日期布尔类型的函数;

  • 序列(list,set)与哈希的函数;

  • 自定义函数 而且FreeMarker中的函数与java中函数调用有个很大的区别,在java中调用函数使用点号(.),而在FreeMarker中使用问号(?),这一点一定要记清。下面分别说上面提到的几种函数:

3.7.1字符串函数

${"abcdef"?substring(2)} <#--从角标是2的位置开始截取到字符串结束-->${"abcdef"?substring(2,4)} <#--从角标是2的位置开始截取到角标是4的位置,包括2不包括4(包前不包后)-->${"abcd mn"?cap_first} <#--将整个字符串的首字母转大写-->${"Abcd"?uncap_first} <#--将整个字符串的首字母转小写-->${"fden eb"?capitalize} <#--将字符串的每个单词首字母转大写-->${"abcd"?ends_with("d")?c} <#--是否以字符d结尾,这个结果是布尔值,不能直接输出,不然会报错,用?c转化成字符串-->${"abcd"?starts_with("d")?c} <#--是否以字符d开头-->${"abac"?index_of("a")} <#--字符a首次出现的位置-->${"abac"?last_index_of("a")} <#--字符a最后一次出现的位置-->${"ab"?left_pad(15,"xy")} <#--将字符串ab填充成15位,如果不够15位,则左边循环填充xy-->${"ab"?right_pad(15,"xy")} <#--将字符串ab填充成15位,如果不够15位,则右边循环填充xy-->${"abac"?contains("ab")?c} <#--判断字符串abac是否包含ab-->${"abac"?replace("ab","AB")} <#--将ab替换成AB--><#list "abcabcabc"?split("c") as s> ${s} <#--将字符串以c字符进行分割,结果是个数组,进行遍历--></#list>${" abc "?trim} <#--去掉字符串空格--><#list " Hello FreeMarker Yes"?word_list as s>${s} <#--将字符串分割成一个个的单词,存在多个空格时,这个跟上面的split分割有一点区别--></#list>

3.7.2数字,日期布尔类型的函数

${4.2?c} <#--以字符串的形式输出,上面说的布尔类型不能直接输出只能转化成字符串这种-->${4.2?string} <#--与?c一样-->${0.42?string.percent} <#--以百分号输出42%-->${4.2?string.currency} <#--以货币形式输出¥4.20-->${4.7?round} <#--四舍五入 -->${4.7?floor} <#--向下取整,floor地板 -->${4.7?ceiling} <#--向上取整,ceiling天花板-->${date?string("yyyy-MM-dd")} <#--传入日期date,以yyyy-MM-dd形式输出,2017-11-18-->${date?date} <#--输出年月日2017-11-18-->${date?time} <#-- 输出时分秒20:41:49-->${date?datetime} <#--输出年月日时分秒-->${false?string("yes","no")} <#--条件如果成功输出yes,否则输出no-->${4.2355?string("0.##")} <#--保留小数点后两位-->

3.7.3 序列(list,set)与哈希的函数

<#assign seq=[1,2,3,4,5,3,10]>${seq?first} <#-- 输出序列seq的第一个-->${seq?last} <#-- 输出序列seq的最后一个-->${seq?seq_contains(6)?c} <#--判断序列是否包含6-->${seq?seq_index_of(3)} <#--3在序列中首次出现的位置-->${seq?seq_last_index_of(3)} <#--3在序列中最后一次出现的位置--><#list seq?reverse as num> <#--翻转序列seq,结果还是一个序列,进行遍历-->${num}</#list>${seq?size} <#--序列seq的长度--><#list seq?sort as num> <#--对序列进行排序-->${num}</#list><#assign seq1=[{"name":"Tom","age":23},{"name":"Jack","age":22},{"name":"Rose","age":21},{"name":"Tim","age":24}]><#list seq1?sort_by("age") as u> <#--以age对哈希seq1进行排序并遍历-->${u.name}+","+${u.age}</#list><#assign users={"name":"Tim","age":24}><#list users?keys as key> <#--获取到哈希users所有的键-->${key}</#list>

3.7.4 自定义函数

<#function add num1 num2> <#return num1+num2></#function><#function addAll nums...> <#local total=0> <#list nums as num> <#local total=total+num> </#list> <#return total></#function><#--使用function指令定义函数add,有两个参数num1和num2,使用return返回计算之后的结果,使用${add(1,3)}调用函数 -->${add(1,3)}<#--使用function指令定义函数addAll,参数个数不固定,定义局部变量total来存储临时计算的结果,遍历所有的参数并进行运算,使用return返回计算之后的结果,使用${addAll(1,2,3,4,5)}调用函数 -->${addAll(1,2,3,4,5)}

4.数据模型

4.1数据类型

使用基本数据类型来派生数字类型使用java.lang.String来构建字符串。使用java.lang.Number来派生数字类型。使用java.lang.Boolean来构建布尔值。使用java.util.List,java.util.Set或Java数组来构建序列。使用java.util.Map来构建哈希表。

 Map root=new HashMap(); root.put("d1", 100); root.put("d2", 100.99); root.put("d3", 'a'); root.put("d4", true); root.put("d5", new Integer(200)); root.put("d6", new Boolean(false)); List<String> names= Arrays.asList("abc","def","ghi"); root.put("d7", names); Set<String> names1=new HashSet<>(); names1.add("ABC"); names1.add("DEF"); names1.add("GHI"); root.put("d8", names1); root.put("d9", new String[]{"a","b","c"}); Map map=new HashMap(); map.put("name", "Java开发日记"); map.put("age", 18); root.put("map", map);

就是java中常见的整型,浮点型,布尔型,字符,数组,list,set,map,不再多说

4.2 加载模板

使用Configuration的方法加载模版:1,void setDirectoryForTemplateLoading(File dir);2,void setClassForTemplateLoading(Class cl, String prefix);3,void setServletContextForTemplateLoading(Object servletContext, String path);加载多个位置的模版:1,FileTemplateLoader2,ClassTemplateLoader3,TemplateLoader4,MultiTemplateLoader5,setTemplateLoader(MultiTemplateLoader mtl);

 Configuration cfg = new Configuration(Configuration.VERSION_2_3_22); //cfg.setClassForTemplateLoading(TemplateLoad.class, "../../../ftl"); FileTemplateLoader ftl1=new FileTemplateLoader(new File("src/ftl")); FileTemplateLoader ftl2=new FileTemplateLoader(new File("src/ftl2")); ClassTemplateLoader ctl=new ClassTemplateLoader(TemplateLoad.class, "../../../ftl3"); TemplateLoader[] loaders={ctl,ftl2}; MultiTemplateLoader mtl=new MultiTemplateLoader(loaders); cfg.setTemplateLoader(mtl); Template template=cfg.getTemplate("ftl2.ftl"); System.out.println(template);

javase项目中使用setDirectoryForTemplateLoading来加载模板所在文件夹,javaee项目中使用setClassForTemplateLoading路径,servlet中可以使用setServletContextForTemplateLoading来加载模板路径。

4.3其它配置

配置就是在对象中存储常用的设置和定义某些想在所有模板中可用的变量,配置对象是freemarker.template.Configuration的实例,可以通过构造方法来创建它。而且一个应用程序通常只使用一个共享的Configuration实例。

  • 设置共享变量:setSharedVariable()

  • 国家地区:setLocale();

  • 数字格式:setNumberFormat("0.##");

  • 通用设置:setSetting(String name, String value)方法

  • 缓存:设置缓存:setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250)) 或setSetting(Configuration.CACHESTORAGEKEY, "strong:20, soft:250");

  • 清空缓存:clearTemplateCache

Configuration cfg=new Configuration(Configuration.VERSION_2_3_22); cfg.setDirectoryForTemplateLoading(new File("src/ftl")); //设置共享便令 cfg.setSharedVariable("site", "Java开发日记"); //设置小数点后保留两位 cfg.setNumberFormat("0.##");、 //设置缓存,一级缓存20个,2级缓存250个 cfg. setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250)); //cfg.setSetting(Configuration.CACHE_STORAGE_KEY, "strong:20, soft:250"); //cfg.clearTemplateCache(); //清楚缓存 Template template = cfg.getTemplate("config.ftl"); Writer writer = new FileWriter(new File("src/finish/config.html"));

总结:上面这些就是FreeMarker模板引擎的基本操作,首先需要进入jar包,之后设置模板所在的路径并引入模板,然后组装数据(实际操作中通过jdbc连接数据库来操作),所以主要学的就两方面内容:模板和数据,而模板又与这许许多多的指令相关,所以必须要掌握这些指令。