FreeMarker 语法详解

字符串

语法

  • substring(start,end):从字符串中截取子串
    start:截取子串开始的索引,start必须大于等于0,小于等于end
    end: 截取子串的长度,end必须大于等于0,小于等于字符串长度,如果省略该参数,默认为字符串长度。
  • cap_first :将字符串中的第一个单词的首字母变为大写。
  • uncap_first:将字符串中的第一个单词的首字母变为小写。
  • capitalize:将字符串中的所有单词的首字母变为大写
  • ends_with 判断某个字符串是否由某个子串结尾,返回布尔值。注意:布尔值必须转换为字符串才能输出
  • index_of(substring,start):在字符串中查找子串的第一个字符的索引,如果没有找到子串,则返回-1。
    Start:参数用于指定从字符串的那个索引处开始搜索,start为数字值。如果start大于字符串长度,则start取值等于字符串长度,如果start小于0, 则start取值为0。
  • length:返回字符串的长度
  • lower_case:将字符串转为小写
  • upper_case:将字符串转为大写
  • contains :判断字符中是否包含某个子串。返回布尔值。注意:布尔值必须转换为字符串才能输出
  • number:将字符串转换为数字
  • replace:将字符串中的一部分从左到右替换为另外的字符串。
  • split:使用指定的分隔符将一个字符串拆分为一组字符串
  • trim:删除字符串首尾空格
  • html:将字符串中的<、>、&和"替换为对应得<>&quot:&amp
  • date,time,datetime将字符串转换为日期,注意:如果指定的字符串格式不正确将引发错误

示例

  • 模板:
字符串连接:${str1 + str2}
字符串截取:${(str)?substring(3,6)}
字符串长度:${(str)?length}
字符串大写:${(str)?upper_case}
字符串小写:${(str)?lower_case}
字符串常指定字符的位置:${(str)?index_of('w')}
字符串常最后一个指定字符的位置:${(str)?last_index_of('o')}
字符串替换:${(str)?replace('o','xx')}
字符串尾字符判断:${str?ends_with("0ER")?string} 返回结果为true
字符串转数字:${"3.1414"?number+22}
字符串转义:${"a>b b<c x&y"?html}
字符串转换为日期:
${date1?date("yyyy-MM-dd")}
${date2?time("HH:mm:ss")}
${date3?datetime("yyyy-MM-dd HH:mm:ss")}

<#--freemarker中的split字符串分割-->
<#list "张三三,李思思,,王强,柳树,诸葛正我"?split(",") as name>
    "${name}"
</#list>
  • 测试代码:
@Test
public void fun4() throws Exception {
    String dir = "src\\main\\resources\\string.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();
    data.put("str1", "1234");
    data.put("str2", "abcd");
    data.put("str","a1s3d5f7Q9W0ER");

    data.put("date1","2009-10-12");
    data.put("date2","9:28:20");
    data.put("date3","2009-10-12 9:28:20");
    //显示生成的数据,//将合并后的数据打印到控制台
    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}

JSON数据

解析JSON数据

示例:

从后台传回的json数据

{
    "number": {
        "one": "111",
        "special": "111",
        "brand": "111",
        "retail": "111"
    },
    "boxNumber": {
        "one": "111",
        "special": "111",
        "brand": "111",
        "retail": "111"
    },
    "price": {
        "one": "111",
        "special": "111",
        "brand": "111",
        "retail": "111"
    }
}

在ftl页面中的解析语法

<#assign text>${pkDetail.detailJson!}</#assign>
<#assign json=text?eval />
<td align="center">${json.number.one!}</td>
<td align="center">${json.number.special!}</td>
<td align="center">${json.number.brand!}</td>
<td align="center">${json.number.retail!}</td>

日期

语法:

  • date: 只显示日期,不显示时间.
    如c r e a t e T i m e ? d a t e 或 {createTime?date} 或createTim**e?dat**e或{createTime?date(‘yyyy-MM-dd’)}
  • time: 只显示时间,不显示日期
    如c r e a t e T i m e ? t i m e 或 {createTime?time} 或createTim**e?tim**e或{createTime?time(‘hh:mm:ss’)}
  • datetime: 时间和日期同时显示
    如c r e a t e T i m e 或 {createTime} 或createTim**e或{createTime?datetime(‘yyyy-MM-dd hh:mm:ss’)}或${createTime?string(‘yyyy-MM-dd hh:mm:ss’)}

示例:

  • 模板文件
输出完整的日期时间部分:${now?datetime}
输出日期部分:${now?date}
输出时间部分: ${now?time}

使用日期格式化样式输出完整的日期时间值
${now?string("yyyy-MM-dd HH:mm:ss zzzz")}
${now?string("EEE, MMM d, ''yy")}
${now?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}
  • 测试代码:
@Test
public void fun5() throws Exception {
    String dir = "src\\main\\resources\\date.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();
    data.put("now", new Date());
    data.put("ss",new Date());

    //显示生成的数据,//将合并后的数据打印到控制台
    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}

数字格式化

  • 模板文件
整数取实际的位数,小数部分保留二位
${num2?string('###.00')}
${num3?string('#.00')}

如果小数点后不足三位,用 0 代替:
${num1?string('0.000')}

如果小数点后多余两位,就只保留两位,否则输出实际值:
${num2?string('#.##')}

整数部分每三位用 , 分割,并且保证小数点后保留两位,不足用 0 代替:
${num3?string(',###.00')}

整数部分每三位用 , 分割,并且小数点后多余三位就只保留三位,不足三位就取实际位数,可以不不包含小数点
${num3?string(',###.###')}

整数部分如果不足三位(000),前面用0补齐,否则取实际的整数位
${num1?string('000.00')}
  • 测试代码:
@Test
public void fun6() throws Exception {
    String dir = "src\\main\\resources\\digit.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();
    data.put("num1", 3.14);
    data.put("num2", 3.141592);
    data.put("num3", 1234567.1415926);

    //显示生成的数据,//将合并后的数据打印到控制台
    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}

遍历对象

  • 模板代码
<#--变量的定义、赋值、运算-->
<#assign a = 50 />
${a}
${a+50}

<#assign d={"deptno":"1111","dname":"operation","loc":"newyork"}/>
${d.deptno}  ${d.dname}  ${d.loc}

${dept}
${dept.dname!"默认值"}
${dept.loc!"默认值"}

assign指令用于在页面上定义一个变量。可以直接一个简单类型,等同于给一个变量赋值;也可以定义个对象类型,取值的时候,根据对象名.属性名,跟JS中一样

  • 测试数据
@Test
public void fun7() throws Exception {
    String dir = "src\\main\\resources\\test2.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();
    data.put("dept",new Dept(10,"sales"));

    //显示生成的数据,//将合并后的数据打印到控制台
    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}

遍历List

  • 模板代码
<#list array as item>
    ${item!}
</#list>

${array?size}
${array[2]}

<#--循环遍历数字,可用于分页-->
<#list 1..8 as i>
    ${i}
</#list>

<#list deptList as dept>
    ${dept_index}  ${dept.deptno} ${dept.dname} ${dept.loc}
</#list>

<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as x>
    ${x_index + 1}.${x}<#if x_has_next>,</#if>
    <#if x="星期三"><#break></#if>
</#list>

其中:

  • item_index:当前变量的索引值
  • item_has_next:是否存在下一个对象
  • <#break>:跳出迭代
  • 测试数据
@Test
public void fun8() throws Exception {
    String dir = "src\\main\\resources\\list.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();
    data.put("array", Arrays.asList("aa", "bb", "cc", "dd"));

    data.put("deptList", Arrays.asList(new Dept(10, "sales", "beijing"),
            new Dept(10, "research", "guangzhou"),
            new Dept(10, "account", "hangzhou"),
            new Dept(10, "operation", "shanghai")));
    //显示生成的数据,//将合并后的数据打印到控制台
    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}

遍历Map

  • 模板代码
<#list scores?keys as key>
    ${key} ${scores[key]!}
</#list>
  • 测试数据
@Test
public void fun9() throws Exception {
    String dir = "src\\main\\resources\\map.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();

    Map<String,Integer> scores = new HashMap<>();
    scores.put("zhangsan",88);
    scores.put("lisi",91);
    scores.put("wanger",78);
    scores.put("mazi",51);

    data.put("scores", scores);
    //显示生成的数据,//将合并后的数据打印到控制台
    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}
  • 当key所对应的值的类型为对象时:

首先在springmvc.xml中FreeMarker中配置如下信息:

<!-- 让FreeMarker支持遍历key为对象的Map -->
<prop key="object_wrapper">freemarker.ext.beans.BeansWrapper</prop>

image-20220527172105131

通过如下方式遍历Map

<#list cart.keySet() as key>
	${key} --- ${cart.get(key)} <br>
</#list>

if

  • 模板代码
<#if flag>
    成功
<#else>
    失败
</#if>

<#if (age>60)>
    老年人
<#elseif (age>40)>
    中年人
<#elseif (age>20)>
    青年人
<#else> 
    少年人
</#if>
  • 测试数据
@Test
public void fun10() throws Exception {
    String dir = "src\\main\\resources\\if.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();
	data.put("age",78);
    data.put("flag",true);
    
    //显示生成的数据,//将合并后的数据打印到控制台
    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}

switch

  • 模板代码
<#switch op>
<#case "login">
    login<#break>
<#case "regist">
    regist<#break>
<#default>
    default
</#switch>
  • 测试数据
@Test
public void fun11() throws Exception {
    String dir = "src\\main\\resources\\switch.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();
    data.put("op","regist");

    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}

字符串和数字比较

在freemarkder中进行了简化,字符串的比较方法和数字做到完全一样,比如:

<#if str == "success">
    xxx
</#if>

<#if str !== 25>
    xxx
</#if>
1234567

数据类型转换

字符串转数字

${'3.1415'?number}

结果:3.1415

数字转字符串

${3.1415?string("number")}
${3.1415?string("currency")}
${3.1415?string("percent")}

结果:
¥3.1415
¥3.1415
314.15%

字符串转date

${"1999-09-21"?date("yyyy-MM-dd")}

结果:1999-09-21

字符串轩time

${"12:12:12"?time("HH:mm:ss")}

结果:12:12:12

字符串转datetime

${"1999-09-21 12:12:12"?datetime("yyyy-MM-dd HH:mm:ss")}

结果:1999-09-21 12:12:12

布尔值转字符串

${true?"真":"假"}

结果:真

空值处理运算符

FreeMarker对空值的处理非常严格,FreeMarker的变量必须有值,没有被赋值的变量就会抛出异常,因为FreeMarker未赋值的变量强制出错可以杜绝很多潜在的错误,如缺失潜在的变量命名,或者其他变量错误.这里所说的空值,实际上也包括那些并不存在的变量,对于一个Java的 null值而言,我们认为这个变量是存在的,只是它的值为null,但对于FreeMarker模板而言,它无法理解null值,null值和不存在的变量完全相同。

  • if_exists:如果存在, 返回该变量值,否者不输出
  • ??:判断某个变量是否存在,??总是返回一个布尔值,用法为:variable??。如果该变量存在,返回true,否则返回false
  • !:指定缺失变量的默认值。用法为:${aaa!’###’},当 aaa 为 null 则返回!后边的内容###。!运算符的用法有variable!或variable!defaultValue两种:
    不指定默认值,表明默认值是空字符串,长度为0的集合,或者长度为0的Map对象
    使用!指定默认值时,并不要求默认值的类型和变量类型相同。
  • 模板代码
${username?if_exists}
<#if username ??>
    存在
<#else>
    不存在
</#if>

${username123!"默认值"}
  • 测试数据
@Test
public void fun12() throws Exception {
    String dir = "src\\main\\resources\\null.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();
    data.put("username","zhangsan");
 
    //显示生成的数据,//将合并后的数据打印到控制台
    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}

import

import指令用于导入FreeMarker模版中的所有变量,并将该变量放置在指定的Map对象中。

示例:

<#import “/libs/myLib.ftl” as my>

include

include指令用于包含指定页,作用类似于JSP的包含指令。

示例:

<#include “/common/copyright.ftl” encoding=”GBK”>
ir = "src\\main\\resources\\null.ftl";//模板路径
    //创建数据模型
    Map<String, Object> data = new HashMap();
    data.put("username","zhangsan");
 
    //显示生成的数据,//将合并后的数据打印到控制台
    Writer out = new StringWriter();

    FreemarkerUtil.execute(dir, data, out);
    System.out.println(out.toString());
}

import

import指令用于导入FreeMarker模版中的所有变量,并将该变量放置在指定的Map对象中。

示例:

<#import “/libs/myLib.ftl” as my>

include

include指令用于包含指定页,作用类似于JSP的包含指令。

示例:

<#include “/common/copyright.ftl” encoding=”GBK”>
  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值