Template Engine-02-模板引擎 Freemarker
拓展阅读
logstash 日志加工处理-08-表达式执行引擎 AviatorScript+MVEL+OGNL+SpEL+JEXL+JUEL+Janino
Spring Boot-07-thymeleaf 模板引擎整合使用
Template Engine-02-模板引擎 Freemarker
Template Engine-03-模板引擎 Freemarker Advance
Template Engine-04-模板引擎 Velocity
Template Engine-05-模板引擎 Thymeleaf 入门介绍
Template Engine-06-模板引擎 Handlebars 入门介绍
Template Engine-07-模板引擎 Mustache 入门介绍 Logic-less templates.
以下是对给出的英文技术文档的中文翻译:
FreeMarker
Apache FreeMarker 是一个模板引擎:一个基于模板和变化数据生成文本输出(HTML 网页、电子邮件、配置文件、源代码等)的 Java 库。
入门指南
模板 + 数据模型 = 输出
模板
Title
Welcome ${user}!
Our latest product:
${latestProduct.name}!
数据模型
- 产品类
public class Product {
private String url;
private String name;
public Product(String url, String name) {
this.url = url;
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 创建 HTML 类的代码
public class Demo {
public static void main(String[] args) throws Exception {
Template template = FreemarkerHelper.getTemplate("demo.ftl");
// 构建映射
Map root = new HashMap();
root.put("user", "echo");
Product product = new Product("www.google.com", "greenhouse");
root.put("latestProduct", product);
FileHelper.createFile(template, "demo.html", root);
}
}
有一些实用工具类如下。
- 获取保存 FTL 和 HTML 的 web 包路径。
public class PathHelper {
public static final String LOCAL_WEB_PATH = "/src/main/web/";
public static String getWebPath() {
String rootPath = System.getProperty("user.dir");
return rootPath + LOCAL_WEB_PATH;
}
}
- 获取 FreeMarker 模板
警告
不要不必要地重新创建 Configuration 实例;这是昂贵的,因为你会失去模板缓存。Configuration 实例意味着是应用级别的 单例。
public class FreemarkerHelper {
private FreemarkerHelper() {}
private static Configuration configuration = null;
/**
* 定义 Configuration
* @return
* @throws Exception
*/
public static Configuration getConfiguration() throws Exception {
if(configuration == null) {
configuration = new Configuration();
configuration.setDirectoryForTemplateLoading(new File(PathHelper.getWebPath())); // 路径
configuration.setObjectWrapper(new DefaultObjectWrapper());
}
return configuration;
}
/**
* 根据 FTL 名称在 web 下获取模板
* @param ftlName
* @return
* @throws Exception
*/
public static Template getTemplate(String ftlName) throws Exception {
Configuration configuration1 = getConfiguration();
Template template = configuration1.getTemplate(ftlName, "UTF-8"); // 默认字符集 UTF-8
return template;
}
}
- 创建文件
public class FileHelper {
/**
* 通过模板、HTML 名称和模型映射创建 HTML;
* @param template
* @param htmlName
* @param map
* @throws Exception
*/
public static void createFile(Template template, String htmlName, Map map) throws Exception {
File file = new File(PathHelper.getWebPath() + htmlName);
if (!file.exists()) {
file.createNewFile();
}
Writer out = new BufferedWriter(new FileWriter(file));
template.process(map, out);
out.flush();
}
}
输出
Title
Welcome echo!
Our latest product:
greenhouse!
基础指令
if
使用 if 指令可以有条件地跳过模板的某个部分。
- 我们将 ftl 更改为如下内容
Title
Welcome ${user}!
echo
not hello
sb. we do not know.
- 输出
Title
Welcome echo!
echo
list
list 指令的通用形式是:
repeatThis.
repeatThis 部分将对您已使用 sequence 指定的每个项目进行重复,从第一个项目开始,一个接一个地。
- 将 Demo.java 更改为如下内容
public class Demo {
public static void main(String[] args) throws Exception {
Template template = FreemarkerHelper.getTemplate("demo.ftl");
//map build
Map map = new HashMap();
List productList = new LinkedList();
Product product = new Product("www.google.com
", "greenhouse");
Product product2 = new Product("www.baidu.com", "bluesky");
productList.add(product);
productList.add(product2);
map.put("productList", productList);
FileHelper.createFile(template, "demo.html", map);
}
}
- ftl 更改为如下内容
Title
${product.name}
- 输出
Title
greenhouse
bluesky
include
使用 include 指令,可以将另一个文件的内容插入到模板中。
- +添加文件 copyright_footer.ftl
版权所有 (c) 2016 Echo,
保留所有权利。
- 将 ftl 更改为如下内容
Title
- 输出
Title
版权所有 (c) 2016 Echo,
保留所有权利。
使用内建方法
丢失的变量
MISS
FreeMarker 中不存在的变量和值为 null 的变量是相同的,因此此处使用的 "missing" 术语涵盖了两种情况。
- 如果缺失会发生什么?
public class Demo {
public static void main(String[] args) throws Exception {
Template template = FreemarkerHelper.getTemplate("demo.ftl");
//map build
Map map = new HashMap();
map.put("user", "this is a long name...");
FileHelper.createFile(template, "demo.html", map);
}
}
Title
${missing}
结果
freemarker.core.InvalidReferenceException: Expression missing is undefined on line 10, column 7 in demo.ftl.
...
- 如何解决这个问题?
将 ftl 更改为如下内容
Title
${missing!'默认值'}
${missing}
缺失
输出
Title
默认值
缺失
Freemarker
Apache FreeMarker is a template engine: a Java library to generate text output
(HTML web pages, e-mails, configuration files, source code, etc.) based on templates and changing data.
Getting Started
Template + data-model = output
Template
Title
Welcome ${user}!
Our latest product:
${latestProduct.name}!
data model
- product class
public class Product {
private String url;
private String name;
public Product(String url, String name) {
this.url = url;
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- create html class code
public class Demo {
public static void main(String[] args) throws Exception {
Template template = FreemarkerHelper.getTemplate("demo.ftl");
//map build
Map root = new HashMap();
map.put("user", "echo");
Product product = new Product("www.google.com", "greenhouse");
map.put("latestProduct", product);
FileHelper.createFile(template, "demo.html", root);
}
}
There are some utility class as following.
- get path of package web which save ftl and html.
public class PathHelper {
public static final String LOCAL_WEB_PATH = "/src/main/web/";
public static String getWebPath() {
String rootPath = System.getProperty("user.dir");
return rootPath + LOCAL_WEB_PATH;
}
}
- get freemarker template
WARN
Do not needlessly re-create Configuration instances; it's expensive, among others because you lose the template cache.
Configuration instances meant to be application-level singletons.
public class FreemarkerHelper {
private FreemarkerHelper() {}
private static Configuration configuration = null;
/**
* define Configuration
* @return
* @throws Exception
*/
public static Configuration getConfiguration() throws Exception {
if(configuration == null) {
configuration = new Configuration();
configuration.setDirectoryForTemplateLoading(new File(PathHelper.getWebPath())); //path
configuration.setObjectWrapper(new DefaultObjectWrapper());
}
return configuration;
}
/**
* Get template by ftl name under web;
* @param ftlName
* @return
* @throws Exception
*/
public static Template getTemplate(String ftlName) throws Exception {
Configuration configuration1 = getConfiguration();
Template template = configuration1.getTemplate(ftlName, "UTF-8"); //default charset UTF-8
return template;
}
}
- create file
public class FileHelper {
/**
* create html by template, htmlName, and modal map;
* @param template
* @param htmlName
* @param map
* @throws Exception
*/
public static void createFile(Template template, String htmlName, Map map) throws Exception {
File file = new File(PathHelper.getWebPath()+htmlName);
if (!file.exists()) {
file.createNewFile();
}
Writer out = new BufferedWriter(new FileWriter(file));
template.process(map, out);
out.flush();
}
}
output
Title
Welcome echo!
Our latest product:
greenhouse!
Base directives
if
With the if directive you can conditionally skip a section of the template.
- we change the ftl like this
Title
Welcome ${user}!
echo
not hello
sb. we do not know.
- output
Title
Welcome echo!
echo
list
The generic form of the list directive is:
repeatThis.
The repeatThis part will be repeated for each item in the sequence that you have specified with sequence, one after the other,
starting from the first item.
- change the Demo.java like this
public class Demo {
public static void main(String[] args) throws Exception {
Template template = FreemarkerHelper.getTemplate("demo.ftl");
//map build
Map map = new HashMap();
List productList = new LinkedList();
Product product = new Product("www.google.com", "greenhouse");
Product product2 = new Product("www.baidu.com", "bluesky");
productList.add(product);
productList.add(product2);
map.put("productList", productList);
FileHelper.createFile(template, "demo.html", map);
}
}
- ftl like this
Title
${product.name}
- output
Title
greenhouse
bluesky
include
With the include directive you can insert the content of another file into the template.
- +add file copyright_footer.ftl
Copyright (c) 2016 Echo,
All Rights Reserved.
- change ftl like this
Title
- output
Title
Copyright (c) 2016 Echo,
All Rights Reserved.
Using built-ins
Missing variables
MISS
A non-existent variable and a variable with null value is the same for FreeMarker, so the "missing" term used here covers both cases.
- what will happen if missing ?
public class Demo {
public static void main(String[] args) throws Exception {
Template template = FreemarkerHelper.getTemplate("demo.ftl");
//map build
Map map = new HashMap();
map.put("user", "this is a long name...");
FileHelper.createFile(template, "demo.html", map);
}
}
Title
${missing}
result
freemarker.core.InvalidReferenceException: Expression missing is undefined on line 10, column 7 in demo.ftl.
...
- how to solve this problem?
change the ftl like this
Title
${missing!'default value'}
${missing}
missing
output
Title
default value
missing
处理纯字符串
有时候我们希望将一穿带有 ${}
的字符串替代掉。
怎么办呢?
测试代码
public static void main(String[] args) throws IOException, TemplateException {
Configuration configuration = Configuration.getDefaultConfiguration();
Template template = new Template("template", "hello ${keyword}", configuration);
StringWriter stringwriter = new StringWriter();
Map map = new HashMap<>();
map.put("keyword", "word");
template.process(map, stringwriter);
System.out.println(stringwriter.toString());
}
这个结果就是:
hello world
chat
详细介绍一下 freemarker
FreeMarker(也称为 Apache FreeMarker)是一个用于生成文本输出(例如HTML网页)的模板引擎。
它是一个开源项目,属于 Apache 软件基金会的项目。
FreeMarker 提供了强大的模板语法和丰富的特性,被广泛用于 Java 等平台的应用程序中。
以下是 FreeMarker 的一些关键特点和功能:
模板语法:
- FreeMarker 使用 FreeMarker Template Language(FTL)作为模板语法。该语法具有清晰、简洁且灵活的特性,支持变量、条件语句、循环、宏等,使得模板编写变得直观和易读。
强大的数据模型:
- FreeMarker 支持丰富的数据模型,包括原始类型、集合、映射、JavaBean 等。模板中可以轻松访问和操作这些数据。
模板继承:
- FreeMarker 支持模板继承和模板包含。可以定义一个基础模板,并在子模板中扩展或覆盖相应的部分。这提高了模板的可维护性和复用性。
内建指令和函数:
- FreeMarker 提供了丰富的内建指令和函数,用于处理模板中的逻辑、数据操作和格式化。例如,内建指令包括
if
、else
、list
、include
等。
- FreeMarker 提供了丰富的内建指令和函数,用于处理模板中的逻辑、数据操作和格式化。例如,内建指令包括
强大的表达式语言:
- FreeMarker 的表达式语言支持复杂的表达式和运算符,以及对字符串、数字、日期等类型的操作。这使得模板中的数据处理更加灵活。
模板缓存:
- FreeMarker 支持模板的缓存,可以在运行时动态加载和编译模板,并将其缓存,以提高性能。缓存机制可以根据需要进行配置,以适应具体的应用场景。
广泛的应用:
- FreeMarker 不仅可以用于生成 HTML 页面,还可以用于生成其他文本格式,如XML、JSON、Markdown等。它广泛应用于 Java Web 框架中,如Spring MVC、Apache Struts 等。
文档和社区支持:
- FreeMarker 提供了详细的文档和示例,帮助用户快速上手。它有一个活跃的社区,用户可以在社区中寻求支持和交流经验。
以下是一个简单的 FreeMarker 模板示例:
${title}
Welcome, ${user.name}!
${role}
在这个示例中,${...}
用于插入变量,`` 用于控制结构,例如 list
用于循环遍历集合。
这是一个简单的展示 FreeMarker 模板语法的例子。
java 使用 freemarker 渲染的入门例子
在 Java 中使用 FreeMarker 渲染模板需要进行一些步骤。以下是一个简单的入门例子,演示如何在 Java 程序中使用 FreeMarker 渲染模板。
首先,确保您已经添加了 FreeMarker 的相关依赖。如果使用 Maven,可以在 pom.xml
文件中添加以下依赖:
org.freemarker
freemarker
2.3.31
然后,可以使用以下示例代码来进行 FreeMarker 模板渲染:
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
public class FreeMarkerExample {
public static void main(String[] args) {
// 初始化 FreeMarker 配置
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
cfg.setClassForTemplateLoading(FreeMarkerExample.class, "/templates");
try {
// 获取模板
Template template = cfg.getTemplate("hello.ftl");
// 创建数据模型
Map data = new HashMap<>();
data.put("title", "FreeMarker Example");
data.put("user", getUserData());
// 渲染模板
StringWriter stringWriter = new StringWriter();
template.process(data, new OutputStreamWriter(System.out));
// 输出渲染结果
System.out.println(stringWriter.toString());
} catch (IOException | TemplateException e) {
e.printStackTrace();
}
}
private static Map getUserData() {
Map user = new HashMap<>();
user.put("name", "John Doe");
user.put("roles", new String[]{"Admin", "User"});
return user;
}
}
在上述示例中:
- 创建
Configuration
对象,设置 FreeMarker 的版本和模板加载路径。 - 获取模板对象,这里假设模板文件位于
/templates/hello.ftl
。 - 创建数据模型,这里创建了一个包含
title
和user
的简单 Map。 - 调用
template.process(data, writer)
方法渲染模板,将数据模型应用到模板中。 - 输出渲染结果。
请注意,hello.ftl
模板文件需要根据实际需求创建。以下是一个简单的示例:
${title}
Welcome, ${user.name}!
${role}
在这个例子中,${...}
用于插入变量,`` 用于控制结构,例如 list
用于循环遍历集合。
根据实际需求,可以创建更复杂的模板文件。