笨蛋学习FreeMarker
- FreeMarker
- 参考网址
- 创建实例
- 引入Maven
- 创建工具类
- 创建实例并进行输出
- FreeMarker数据类型
- 布尔型:
- 日期型:
- 数值型:
- 字符型:
- 需要处理字符串为null的情况,否则会报错
- 字符串为空不会报错
- cap_first
- uncap_first
- upper_case
- lower_case
- capitalize
- chop_linebreak
- contains
- ends_with
- ensure_ends_with
- ensure_starts_with
- groups
- html
- index_of
- j_string
- js_string
- json_string
- keep_after
- keep_after_last
- keep_before
- keep_before_last
- last_index_of
- length
- lower_case
- matches
- number
- replace
- rtf
- split
- starts_with
- trim
- word_list
- xhtml
- xml
- sequence类型:
- hash类型:
- FreeMarker指令
- #assign定义变量
- #if #elseif #else逻辑判断
- #list遍历
- #macro自定义
- 创建自定义指令
- 使用自定义指令
- nested占位
- import导入模板
- include包含模板或文件
- FreeMarker运算符
- 算术运算符
- 逻辑运算符
- 比较运算符
- 空值运算符
FreeMarker
参考网址
http://freemarker.foofun.cn/
创建实例
引入Maven
<!-- 模板引擎-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.33</version>
</dependency>
创建工具类
/**
* FreeMarker 工具类,用于处理模板和生成输出文件
*/
public class FreeMarkerTemplate{
private Configuration configuration;
/**
* 构造函数,初始化 FreeMarker 配置
*
* @param templateDirectory 模板文件存放的目录
*/
public FreeMarkerTemplate(String templateDirectory) {
configuration = new Configuration(Configuration.VERSION_2_3_31);
configuration.setClassForTemplateLoading(FreeMarkerTemplate.class, templateDirectory);
configuration.setDefaultEncoding("UTF-8");
}
/**
* 处理模板并生成输出文件
*
* @param templateName 模板文件名
* @param model 模板数据模型,即要传递给模板的参数
* @param outputFilePath 输出文件路径
*/
public void processTemplate(String templateName, Map<String, Object> model, String outputFilePath) {
try {
// 加载指定的模板文件
Template template = configuration.getTemplate(templateName);
// 生成输出文件
try (Writer out = new FileWriter(new File(outputFilePath))) {
template.process(model, out); // 将模型数据填充到模板中
}
System.out.println("输出已生成: " + outputFilePath);
} catch (IOException | TemplateException e) {
e.printStackTrace(); // 处理异常,可以根据需要完善异常处理
}
}
}
创建实例并进行输出
Map<String, Object> model = new HashMap<>();
model.put("msg", "TodaySaturday");
// 创建 FreeMarker 工具类实例,指定模板目录(一般在resource目录下创建一个文件夹存放模板)
FreeMarkerTemplate freeMarkerUtil = new FreeMarkerTemplate("/templates");
// 调用工具类方法处理模板,生成输出文件
freeMarkerUtil.processTemplate("convertHtml.ftl", model, "TodaySaturday-GenApi.html");
FreeMarker数据类型
布尔型:
相当于boolean类型,但是不能直接输出,需要转字符串输出
-
使用
?c
和?msg
来进行转字符串 -
${msg?c} ${msg?string} <!--如果是true返回yes,否则返回false--> ${msg?string("yes","no")}
日期型:
相当于date类型,但是不能直接输出,需要转字符串输出
-
年月日:
?date
-
时分秒:
?time
-
年月日时分秒:
?datetime
-
指定格式:
?string("自定义格式")
- y:年
- M:月
- d:日
- H:时
- m:分
- s:秒
-
${myDate?date} ${myDate?time} ${myDate?datetime} ${myDate?string("yyyy年MM月dd日 HH时mm分ss秒")}
数值型:
相当于int、float、double、lang等数值类型
- 可以转换为数值型、货币型、百分比型
- 转字符串:
?c
- 转货币型字符串:
?string.currency
- 转百分比型字符串:
?string.percent
- 保留小数:
?string["0.##"]
,#表示一个小数位
字符型:
相当于字符串,有很多内置函数
-
需要处理字符串为null的情况,否则会报错
!
:指定缺失变量的默认值,${value!}
: 如果value值为空,则默认值是空字符串${value!"默认值"}
:如果value值为空,则默认值为 ”默认值“
??
:判断变量是否存在,如果变量存在,返回true,否则返回false${value??}?string
-
字符串为空不会报错
-
cap_first
字符串中的首单词的首字母大写。
${" green mouse"?cap_first} ${"GreEN mouse"?cap_first} ${"- green mouse"?cap_first}
-
uncap_first
和 cap_first
相反。 字符串中所有单词的首字母小写。
字符串的大写形式。比如 "GrEeN MoUsE"
将会是 "GREEN MOUSE"
.
字符串的小写形式。比如 "GrEeN MoUsE"
将会是 "green mouse"
.
字符串中所有单词的首字母大写。
${" green mouse"?capitalize}
${"GreEN mouse"?capitalize}
在末尾没有 换行符 的字符串, 那么可以换行,否则不改变字符串。
如果函数中的参数指定的子串出现在源字符串中, 那么返回true。
<#if "piceous"?contains("ice")>It contains "ice"</#if>
返回是否这个字符串以参数中指定的子串结尾。
"ahead"?ends_with("head")
返回 true
"head"?ends_with("head")
返回 true
。
如果字符串没有以第一个参数指定的子串结尾, 那么就会将它加到字符串后面,否则返回原字符串。
"foo"?ensure_ends_with("/")
"foo/"?ensure_ends_with("/")
返回 "foo/"
。
如果字符串没有以第一个参数指定的子串开头, 那么就会将它加到字符串开头,否则返回原字符串。
"foo"?ensure_starts_with("/")
"/foo"?ensure_starts_with("/")
返回 "/foo"
。
这个函数只作用于内建函数 matches
的结果。请参考 这里…。
<input type=text name=user value="${user?html}">
返回第一次字符串中出现子串时的索引位置。
"abcabc"?index_of("bc")
将会返回1 (不要忘了第一个字符的索引是0)。而且,你可以指定开始搜索的索引位置: "abcabc"?index_of("bc", 2)
将会返回4。 这对第二个参数的数值没有限制:如果它是负数,那就和是0是相同效果了, 如果它比字符串的长度还大,那么就和它是字符串长度那个数值是一个效果。 小数会被切成整数。
根据Java语言字符串转义规则来转义字符串, 所以它很安全的将值插入到字符串类型中。要注意它 不会 在被插入的值的两侧添加引号; 你需要在字符串值 内部 来使用。
<#assign beanName = 'The "foo" bean.'>
String BEAN_NAME = "${beanName?j_string}";
String BEAN_NAME = "The \"foo\" bean.";
根据JavaScript语言字符串转义规则来转义字符串, 所以它很安全的将值插入到字符串类型中。要注意, 它不会在被插入的值两侧添加引号
引号("
)和单引号('
)要被转义。 也要将 >
转义为 \>
(为了避免 </script>
)。
<#assign user = "Big Joe's \"right hand\"">
<script>
alert("Welcome ${user?js_string}!");
</script>
将会输出:
<script>
alert("Welcome Big Joe\'s \"right hand\"!");
</script>
根据JSON语言的字符串规则来转义字符串, 所以在字符串中插入值是安全的。 要注意它 不会 在被插入的值两侧添加引号; 你需要在字符串值 内部 来使用。
这不会转义 '
字符,因为JSON字符串必须使用 "
来括起来。它会在 <
之后直接出现的 /
(斜杠)字符转义为 \/
, 来避免 </script>
等。 它也会在 ]]
之后转义 >
字符为 \u003E
,来避免退出XML的 CDATA
段。
移除字符串中的一部分内容,该部分是给定子串第一次出现之前的部分。
${"abcdefgh"?keep_after("de")}
如果参数字符串没有找到,它会返回空串。如果参数是长度为0的字符串, 它会返回源字符串,不会改变。
该方法接受可选的 标志位参数,作为它的第二个参数:
${"foo : bar"?keep_after(r"\s*:\s*", "r")}
和 keep_after
相同, 但是它会保留参数最后一次出现后的部分,而不是第一次。比如:
${"foo.bar.txt"?keep_after_last(".")}
若使用 keep_after
则会得到 bar.txt
。
移除字符串的一部分,该部分是从给定子串开始的部分。 比如:
${"abcdef"?keep_before("de")}
如果参数字符串没有找到,它会返回源字符串,不会改变。 如果参数是长度为0的字符串,它会返回空串。
该方法接受可选的 标志位参数,作为它的第二个参数:
${"foo : bar"?keep_before(r"\s*:\s*", "r")}
和 keep_before
相同, 但是保留参数最后一次出现之前的部分,而不是第一次出现之前。
${"foo.bar.txt"?keep_after_last(".")}
返回最后一次(最右边)字符串中出现子串时的索引位置。 它返回子串第一个(最左边)字符所在位置的索引。例如: "abcabc"?last_index_of("ab")
:将会返回3。
字符串中字符的数量。
字符串的小写形式。
"GrEeN MoUsE"?lower_case
将会是 "green mouse"
。
-
matches
- 布尔值:如果字符串整体匹配了模式,就是
true
, 否则就是false
。比如:"fooo"?matches('fo*')
就是true
,但是"fooo bar"?matches('fo*')
是false
。 - 序列:字符串匹配的子串的列表。很有可能是长度为0的序列。
- 布尔值:如果字符串整体匹配了模式,就是
-
number
字符串转化为数字格式。这个数字必须是 “计算机语言” 格式。也就是说, 它必须是本地化独立的形式,小数的分隔符就是一个点,没有分组。
在源字符串中,用另外一个字符串来替换原字符串中出现它的部分。 它不处理词的边界。比如:
${"this is a car acarus"?replace("car", ulldozer")}
将会输出:
this is a bulldozer abulldozerus
替换是从左向右执行的。这就意味着:
${"aaaaa"?replace("aaa", "X")}
如果第一个参数是空字符串,那么所有的空字符串将会被替换, 比如 "foo"?replace("","|")
,就会得到 "|f|o|o|"
。
replace
接受可选的 标志位参数,作为它的第三参数。
它被用来根据另外一个字符串的出现将原字符串分割成字符串序列。 比如:
<#list "someMOOtestMOOtext"?split("MOO") as x>
- ${x}
</#list>
- "some"
- ""
- "test"
- "text"
- ""
split
接受可选的 标志位参数, 作为它的第二个参数。由于历史使用 r
(正则表达式)标志的差错;它会从结果列表中移除空元素, 所以在最后示例中使用 ?split(",", "r")
, ""
会从输出中消失。
如果字符串以指定的子字符串开头,那么返回true
。
"redirect"?starts_with("red")
返回布尔值 true
,
"red"?starts_with("red")
也返回 true
。
去掉字符串首尾的空格。例如:
(${" green mouse "?trim})
包含字符串中所有单词的序列,顺序为出现在字符串中的顺序。 单词是不间断的字符序列,包含了任意字符,但是没有 空白。例如:
<#assign words = " a bcd, . 1-2-3"?word_list>
<#list words as word>[${word}]</#list>
将会输出:
[a][bcd,][.][1-2-3]
该内建函数和 xml
内建函数的唯一不同是 xhtml
内建函数转义 '
为 '
,而不是 '
, 因为一些老版本的浏览器不能正确解释 '
。
sequence类型:
相当于数组、List、Set等集合类型
-
不能直接操作数组
${arr}
,需要使用指令来输出序列类型 -
输出序列
-
<#list arr as ele> ${ele}-${ele?index} </#list>
-
-
获取序列的长度:
${arr?sizt}
-
获取序列的第一个元素:
${arr?first}
-
获取序列的最后一个元素:
${arr?last}
-
倒叙输出序列:
-
<#list arr?reverse as ele> ${ele}-${ele?index} </#list>
-
-
升序输出序列:
-
<#list arr?sort as ele> ${ele}-${ele?index} </#list>
-
-
降序输出序列:
-
<#list arr?sort?reverse as ele> ${ele}-${ele?index} </#list>
-
hash类型:
相当于map类型
- 不能直接操作hash
${maps}
,需要使用指令来输出hash类型
<#list maps?keys as key>
${key}-${maps[key]}
</#list>
<#list maps?values as value>
${value}
</#list>
FreeMarker指令
#assign定义变量
<#assign str="hello">
${str}
<#assign num=1 >
#if #elseif #else逻辑判断
<#assign sum=60 >
<#if>
<#elseif sum gt 60 && sum lt 80>
合格
<#else >
不合格
</#if>
#list遍历
<#if user??>
<#list arr?sort?reverse as ele>
${ele}-${ele?index}
</#list>
</#if>
<#assign arr=[]>
<#list arr?sort?reverse as ele>
${ele}-${ele?index}
<#else>
如果arr为空,就执行这里的内容
</#list>
#macro自定义
创建自定义指令
<#macro hello>
Hello World
<#macro>
-----------------------
<#macro sum num1 num2>
${num1} + ${num2}
<#macro>
-----------------------
<#macro chengfabiao>
<#list 1..9 as i>
<#list 1..i as j>
${j} * ${i} = ${j*i}  
</#list>
</#list>
<#macro>
使用自定义指令
<@hello></@hello>
------------------------
<@sum 10 10></@sum 10 10>
------------------------
<@chengfabiao></@chengfabiao>
nested占位
- <@ 指令名>占位内容</@ 指令名>
- 占位内容会替换掉自定义指令中的<#nested>
<#macro hello>
Hello <#nested>
<#macro>
--------------------------
<@hello>World</@hello>
import导入模板
- 创建一个模板 ftlOne.ftl
<#macro hello>
Hello <#nested>
<#macro>
<#macro helloworld>
Hello World!!!
<#macro>
- 在ftlTwo.ftl中调用ftlOne.ftl
<#import "ftlOne.ftl" as one>
<@one.hello World>
<@one.helloworld>
include包含模板或文件
- 定义一个html文件 index.html(模板同理)
- 在indexDemo.html中调用
<#include "index.html">
FreeMarker运算符
算术运算符
- +、-、*、/、%,如果是多个字段必须在
${}
中使用
逻辑运算符
- &&、||、!
比较运算符
> (gt)
:大于< (gl)
:小于> (gte)
:大于等于< (gle)
:小于等于==
:等于!=
:不等于
空值运算符
!
:指定缺失变量的默认值,${value!}
: 如果value值为空,则默认值是空字符串${value!"默认值"}
:如果value值为空,则默认值为 ”默认值“
??
:判断变量是否存在,如果变量存在,返回true,否则返回false${value??}?string