什么是Freemarker
链接: Freemarker介绍和语法
FreeMarker 是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。
实现代码
创建一个test.json
{
"fileId": "${id}",
"name": "${name}",
"date": "<#if date??>${date?string('yyyy-MM-dd HH:mm:ss')}<#else></#if>",
"id": "${id}"
}
Freemarker工具类
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.*;
import java.nio.charset.StandardCharsets;
/**
* Freemarker工具类
* @author zhou
*/
public class MyFreemarkerUtil {
private final static String ENCODING = "utf-8";
/**
* resources下的目录
*/
private final static String BASE_PACKAGE_PATH = "/freemarker";
private static final MyFreemarkerUtil INSTANCE = new MyFreemarkerUtil();
private final Configuration configuration;
/**
* 应该使用单实例配置(也就是说,它是单例的)。
* 请注意不管一个系统有多少独立的组件来使用 FreeMarker,它们都会使用他们自己私有的 Configuration 实例。
* 不需要重复创建 Configuration实例; 它的代价很高,尤其是会丢失缓存。Configuration实例就是应用级别的单例。
* 注意Configuration实例有缓存
*/
private MyFreemarkerUtil() {
// org.freemarker version
configuration = new Configuration(Configuration.VERSION_2_3_30);
configuration.setDefaultEncoding(ENCODING);
//选择模板保存路径resources下
configuration.setClassForTemplateLoading(MyFreemarkerUtil.class, BASE_PACKAGE_PATH);
}
public static MyFreemarkerUtil getInstance() {
return INSTANCE;
}
/**
* 根据ftl模板生成字符串
* @param data
* @param ftlName
* @return
*/
public static String generateStr(Object data, String ftlName) throws IOException, TemplateException {
// 输出文档路径及名称
//以utf-8的编码读取ftl文件
MyFreemarkerUtil instance = MyFreemarkerUtil.getInstance();
Template template = instance.configuration.getTemplate(ftlName, ENCODING);
StringWriter out = new StringWriter();
template.process(data, out);
return out.toString();
}
/**
* 根据ftl模板生成文件
* @param data
* @param ftlName
* @param outFilePath
*/
public static void generateFile(Object data, String ftlName, String outFilePath) throws IOException {
MyFreemarkerUtil instance = MyFreemarkerUtil.getInstance();
Template template = instance.configuration.getTemplate(ftlName);
File file = new File(outFilePath);
try (FileOutputStream fileOutputStream = new FileOutputStream(file);
OutputStreamWriter outputStream = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8)
) {
StringWriter out = new StringWriter();
template.process(data, out);
String content = out.toString();
outputStream.write(content);
outputStream.flush();
fileOutputStream.flush();
} catch (IOException | TemplateException e) {
e.printStackTrace();
}
}
}
main
public static void main(String[] args) throws IOException, TemplateException {
// 假设我们有一个Map来表示数据模型
Map<String, Object> datas = new HashMap<>();
datas.put("id", 30);
datas.put("name", "name");
datas.put("date", null);
String s = MyFreemarkerUtil.generateStr(datas, "test.json");
JSONObject jsonObject = JSONObject.parseObject(s);
System.out.println(jsonObject);
}
代码升级版
FreemarkerConfigurationBuildFatroy
import freemarker.template.Configuration;
import java.io.File;
import java.io.IOException;
/**
* @author zhou
*/
public class FreemarkerConfigurationBuildFatroy {
private final static String ENCODING = "utf-8";
/**
* resources下的目录
*/
private final static String BASE_PACKAGE_PATH = "/freemarker";
/**
* 选择模板保存路径(本地磁盘)
* @param filePath
* @return
* @throws IOException
*/
public static Configuration getConfigurationForFile(String filePath) throws IOException {
// org.freemarker version
Configuration configuration = new Configuration(Configuration.VERSION_2_3_30);
configuration.setDefaultEncoding(ENCODING);
// 选择模板保存路径(本地磁盘)
configuration.setDirectoryForTemplateLoading(new File(filePath));
return configuration;
}
/**
* 选择模板保存路径resources下
*/
public static Configuration getConfigurationForClass(){
// org.freemarker version
Configuration configuration = new Configuration(Configuration.VERSION_2_3_30);
configuration.setDefaultEncoding(ENCODING);
// 选择模板保存路径resources下
configuration.setClassForTemplateLoading(FreemarkerConfigurationBuildFatroy.class, BASE_PACKAGE_PATH);
return configuration;
}
}
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
/**
* @author zhou
*/
public class FreemarkerBean {
private final static String ENCODING = "utf-8";
private static final Logger logger = LoggerFactory.getLogger(FreemarkerBean.class);
private final Configuration configuration;
public FreemarkerBean(Configuration configuration) {
this.configuration = configuration;
}
public Template getTemplate(String ftlName) throws IOException {
return configuration.getTemplate(ftlName, ENCODING);
}
/**
* 动态构建前端展示组件的JSON格式
* @param datas
* @param ftlPath
* @return
*/
public String buildJsonStr(Map<String, Object> datas, String ftlPath) {
try {
Template template = getTemplate(ftlPath);
StringWriter out = new StringWriter();
template.process(datas, out);
return out.toString();
} catch (IOException | TemplateException e) {
logger.error("buildJsonStr error {}", e.getMessage());
// 自行处理异常...
}
}
public void init() {
logger.info("FreemarkerBean ... init...");
}
public void detory() {
logger.info("FreemarkerBean ... destory...");
}
}
public static void main(String[] args){
// 假设我们有一个Map来表示数据模型
Map<String, Object> datas = new HashMap<>();
datas.put("name", "name");
datas.put("date", null);
datas.put("id", 30);
Configuration configuration = FreemarkerConfigurationBuildFatroy.getConfigurationForClass();
FreemarkerBean freemarkerBean = new FreemarkerBean(configuration);
String s = freemarkerBean.buildJsonStr(datas, "test.json");
System.out.println(s);
}
注意
链接: Freemarker介绍和语法
Warning!
不需要重复创建 Configuration 实例; 它的代价很高,尤其是会丢失缓存。Configuration 实例就是应用级别的单例。
常用语法
数字内建函数
给出数字的绝对值
给出数字的绝对值。比如 x?abs ,如果 x 是 -5,会得到5。
该内建函数从 FreeMarker 2.3.20 版本开始存在。
保留位数
<#assign x = 1.234>
${x?string["0"]}
${x?string["0.#"]}
${x?string["0.##"]}
${x?string["0.###"]}
输出
1
1.2
1.23
1.234
<#setting number_format=",##0.00">
<#setting locale="en_US">
US people write: ${12345678}
<#setting locale="hu">
German people write: ${12345678}
输出
US people write: 12,345,678.00
German people write: 12.345.678,00
1
1
1
1