笨蛋学习FreeMarker

Alt

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 相反。 字符串中所有单词的首字母小写。

  • upper_case

字符串的大写形式。比如 "GrEeN MoUsE" 将会是 "GREEN MOUSE".

  • lower_case

字符串的小写形式。比如 "GrEeN MoUsE" 将会是 "green mouse".

  • capitalize

字符串中所有单词的首字母大写。

${"  green  mouse"?capitalize}
${"GreEN mouse"?capitalize}
  • chop_linebreak

在末尾没有 换行符 的字符串, 那么可以换行,否则不改变字符串。

  • contains

如果函数中的参数指定的子串出现在源字符串中, 那么返回true。

<#if "piceous"?contains("ice")>It contains "ice"</#if>
  • ends_with

返回是否这个字符串以参数中指定的子串结尾

"ahead"?ends_with("head") 返回 true

"head"?ends_with("head") 返回 true

  • ensure_ends_with

如果字符串没有以第一个参数指定的子串结尾, 那么就会将它加到字符串后面,否则返回原字符串。

"foo"?ensure_ends_with("/")

"foo/"?ensure_ends_with("/") 返回 "foo/"

  • ensure_starts_with

如果字符串没有以第一个参数指定的子串开头, 那么就会将它加到字符串开头,否则返回原字符串。

"foo"?ensure_starts_with("/")

"/foo"?ensure_starts_with("/") 返回 "/foo"

  • groups

这个函数只作用于内建函数 matches 的结果。请参考 这里…

  • html
    • < 替换为 <
    • > 替换为 >
    • & 替换为 &
    • " 替换为 "
<input type=text name=user value="${user?html}">
  • index_of

返回第一次字符串中出现子串时的索引位置。

"abcabc"?index_of("bc") 将会返回1 (不要忘了第一个字符的索引是0)。而且,你可以指定开始搜索的索引位置: "abcabc"?index_of("bc", 2) 将会返回4。 这对第二个参数的数值没有限制:如果它是负数,那就和是0是相同效果了, 如果它比字符串的长度还大,那么就和它是字符串长度那个数值是一个效果。 小数会被切成整数。

  • j_string

根据Java语言字符串转义规则来转义字符串, 所以它很安全的将值插入到字符串类型中。要注意它 不会 在被插入的值的两侧添加引号; 你需要在字符串值 内部 来使用。

<#assign beanName = 'The "foo" bean.'>
String BEAN_NAME = "${beanName?j_string}";
String BEAN_NAME = "The \"foo\" bean.";
  • js_string

根据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_string

根据JSON语言的字符串规则来转义字符串, 所以在字符串中插入值是安全的。 要注意它 不会 在被插入的值两侧添加引号; 你需要在字符串值 内部 来使用。

这不会转义 ' 字符,因为JSON字符串必须使用 " 来括起来。它会在 < 之后直接出现的 /(斜杠)字符转义为 \/, 来避免 </script> 等。 它也会在 ]] 之后转义 > 字符为 \u003E,来避免退出XML的 CDATA 段。

  • keep_after

移除字符串中的一部分内容,该部分是给定子串第一次出现之前的部分。

${"abcdefgh"?keep_after("de")}

如果参数字符串没有找到,它会返回空串。如果参数是长度为0的字符串, 它会返回源字符串,不会改变。

该方法接受可选的 标志位参数,作为它的第二个参数:

${"foo : bar"?keep_after(r"\s*:\s*", "r")}
  • keep_after_last

keep_after 相同, 但是它会保留参数最后一次出现后的部分,而不是第一次。比如:

${"foo.bar.txt"?keep_after_last(".")}

若使用 keep_after 则会得到 bar.txt

  • keep_before

移除字符串的一部分,该部分是从给定子串开始的部分。 比如:

${"abcdef"?keep_before("de")}

如果参数字符串没有找到,它会返回源字符串,不会改变。 如果参数是长度为0的字符串,它会返回空串。

该方法接受可选的 标志位参数,作为它的第二个参数:

${"foo : bar"?keep_before(r"\s*:\s*", "r")}
  • keep_before_last

keep_before 相同, 但是保留参数最后一次出现之前的部分,而不是第一次出现之前。

${"foo.bar.txt"?keep_after_last(".")}
  • last_index_of

返回最后一次(最右边)字符串中出现子串时的索引位置。 它返回子串第一个(最左边)字符所在位置的索引。例如: "abcabc"?last_index_of("ab"):将会返回3。

  • length

字符串中字符的数量。

  • lower_case

字符串的小写形式。

"GrEeN MoUsE"?lower_case 将会是 "green mouse"

  • matches
    • 布尔值:如果字符串整体匹配了模式,就是 true, 否则就是 false。比如:"fooo"?matches('fo*') 就是 true,但是 "fooo bar"?matches('fo*')false
    • 序列:字符串匹配的子串的列表。很有可能是长度为0的序列。
  • number

字符串转化为数字格式。这个数字必须是 “计算机语言” 格式。也就是说, 它必须是本地化独立的形式,小数的分隔符就是一个点,没有分组。

  • replace

在源字符串中,用另外一个字符串来替换原字符串中出现它的部分。 它不处理词的边界。比如:

${"this is a car acarus"?replace("car", ulldozer")}

将会输出:

this is a bulldozer abulldozerus

替换是从左向右执行的。这就意味着:

${"aaaaa"?replace("aaa", "X")}

如果第一个参数是空字符串,那么所有的空字符串将会被替换, 比如 "foo"?replace("","|"),就会得到 "|f|o|o|"

replace 接受可选的 标志位参数,作为它的第三参数。

  • rtf
    • \ 替换为 \\
    • { 替换为 `{``
    • } 替换为 \}
  • split

它被用来根据另外一个字符串的出现将原字符串分割成字符串序列。 比如:

<#list "someMOOtestMOOtext"?split("MOO") as x>
- ${x}
</#list>
- "some"
- ""
- "test"
- "text"
- ""

split 接受可选的 标志位参数, 作为它的第二个参数。由于历史使用 r (正则表达式)标志的差错;它会从结果列表中移除空元素, 所以在最后示例中使用 ?split(",", "r")"" 会从输出中消失。

  • starts_with

如果字符串以指定的子字符串开头,那么返回true

"redirect"?starts_with("red") 返回布尔值 true

"red"?starts_with("red") 也返回 true

  • trim

去掉字符串首尾的空格。例如:

(${"  green mouse  "?trim})
  • word_list

包含字符串中所有单词的序列,顺序为出现在字符串中的顺序。 单词是不间断的字符序列,包含了任意字符,但是没有 空白。例如:

<#assign words = "   a bcd, .   1-2-3"?word_list>
<#list words as word>[${word}]</#list>

将会输出:

[a][bcd,][.][1-2-3]
  • xhtml
    • < 替换为 <
    • > 替换为 >
    • & 替换为 &
    • " 替换为 "
    • ' 替换为 '

该内建函数和 xml 内建函数的唯一不同是 xhtml内建函数转义 '',而不是 ', 因为一些老版本的浏览器不能正确解释 '

  • xml
    • < 替换为 <
    • > 替换为 >
    • & 替换为 &
    • " 替换为 "
    • ' 替换为 '

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} &nbsp
    	 </#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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值