Freemarker专题

变量的定义与显示

1.定义字符串

<#assign str='a'>
<#assign str2 ="b">
<#assign sb =str+str2>${sb}结果为ab
<#assign sb =str+1>${sb}结果为a1

2.定义数字

<#assign x = 1>
<#assign y = 2>
<#assign z = x+y>  ${z}结果为3

3.定义list

<#assign list0 = [0,1,"2"]>

4.定义map

<#assign map0 = {"1":"a","2":"b"}>

5.定义boolean类型

<#assign bl= false>
${bl?c}显示false

变量的运算

1.都为数值类型时 为正常运算
2.其中有字符串时为字符串拼接

基础标签

1.条件判断<#if (bl)>

<#assign a = 2>
<#if (a=1)>
  a=1
  <#elseif (a=2)>
  a=2
  <#else>
  a=other
</#if>

2.循环标签与中断标签<#list list as obj>

<#list list as obj>
   <#if (obj_index=2)><#break></#if>
</#list>

3.禁止转换标签<#noparse>

<#noparse>
${a}
</#noparse>//被noparse包围的区域将不会被转换,结果显示${a}

4.导入其他freemarker文本标签<#include>
a. 创建base.ftl如下

<#assign a = 1>
abc

b. 创建test.ftl如下

<#include '../base.ftl'>//中的文本与变量同时被导入进来
${a}  
显示结果为
abc
1

5.导入定义与函数标签<#import as xxx>
a. 创建base.ftl如下

<#assign a = 1>
abc

b. 创建test.ftl如下

<#import '../base.ftl' as obj>//中的文本与变量同时被导入进来
${obj.a}  
显示结果为
1

List的使用

1.list偏移

<#assign list = [1,2,"3"]>
${list[0]+list[1]}

2.list判断存在元素

<#assign list = [1,2,"3"]>
${list?seq_contains(1)?c}显示true
${list?seq_contains("3")?c}显示true

3.list的大小

${list?size}

4.list的遍历

<#list list as obj>
${obj_index}.${obj}  //x_index为list的索引
</#list>

Map的使用

1.map遍历key

<#assign map = {"1":"a","2":"b","3":"c"}>
<#list map?keys as key>
${key}:${map[key]}
</#list>

2.map查找value

<#assign key="2">
${map[key]}或${map["2"]}

3.判断map是否存在某个key

${map["2"]?exists?string('存在','不存在')}
${map?keys[1]?exists?string('存在','不存在')}

Freemarker技巧

1.打印$

<#assign dl='$'>
${dl}
${r'$abc'}

2.避免未定义变量(miss)错误

${a!""}
<#assign a = 'a'><#assign b = 'b'>
${(a+b+":")!""}//若a或b其中一个不存在则为""都存在则为ab:
${a?default("0")}

3.格式化数据

#{2.555;M2}//最多保留两位小数  结果为2.56
#{2;M2}//最多保留两位小数  结果为2
#{2.555;m2}//保留到两位小数  结果为2.56
#{2;m2}//保留到两位小数  结果为2.00
${123456?string(',###')}//每3位用逗号分割 结果为123,456
${123456.1?string(',###.##')}//每3位用逗号分割并最多保留两位小数 结果为123,456.1
${123456.1?string(',###.00')}//每3位用逗号分割并保留到2位小数 结果为123,456.10
${datetime?string('yyyy-MM-dd HH:mm')} //格式化日期

4.去掉空格与换行符

<#t> 去掉左右空白和回车换行 
<#lt>去掉左边空白和回车换行 
<#rt>去掉右边空白和回车换行 
<#nt>取消上面的效果 

常用函数

1.exists判断该变量是否存在
2.is_sequence判断变量是否是集合
3.is_hash判断变量是否是map

字符串函数

${"abc"?length}  //字符串长度
${" abc "?trim}  //去掉左右空格
${"1"?number+2}  //转换数字类型  结果为3
${" abc "?substring(1,3)}  //字符串截取
${"abcabd"?replace('a','c')} //替换所有字符
${"abcabd"?split('b')[0]} //分割字符串
${" abc "?index_of('a')}  //第一个字符串索引
${" abc "?last_index_of('a')}  //最后一个字符串索引
${"abc"?cap_first}  //首字母大写
${"abc"?uncap_first}  //首字母小写
${"abc"?upper_case}  //全部字母大写
${"abc"?lower_case}  //全部字母小写
${"abcabd"?starts_with('b')?c}  //判断是否以某字符串开头
${"abcabd"?ends_with('b')?c}//判断是否以某字符串结尾
${"abc"?contains('b')?c} //判断是否包含字符
${"123"?matches('\\d+')?c}  //判断是否匹配正则表达式
${"<>&"?html} //html转码
<#setting url_escaping_charset='UTF-8'>
${"localhost/a.html?name=李渊"?url}或者
${"localhost/a.html?name=李渊"?url('UTF-8')}//url编码

Freemarker高级用法

1.自定义指令<#macro method param0 param1="?" param2="?"></#macro>

<#macro hello name="lg">hello ${name}</#macro>
<@hello name='world'/>//结果显示 hello world 

2.java中自定义指令
a. 创建类并实现TemplateDirectiveModel接口
b. 使用env输出数据

public class TestDirective implements TemplateDirectiveModel {
    
    public void execute(Environment env, Map params, TemplateModel[] loopVars,
            TemplateDirectiveBody body) throws TemplateException, IOException {
        env.getOut().write("-----------------------");
        SimpleScalar ss = (SimpleScalar) params.get("name");
        String name = ss.getAsString();
        if(name!=null){
            env.getOut().write(name);
        }
    }
}

c. 在ftl文件中引入java方法,并使用

<#assign test= "net.lgpage.ant.test.UpperDirective2"?new()> //引入方法
<@test name='lg'></@upper>//输出结果-----------------------lg
  1. 自定义函数 <#function avg param0 param1><#return '?'/></#function>
<#function test a>
    <#return 'hello ${a}'>
</#function>
${test('world')}//输出hello world
  1. java中自定义函数
    a. 实现TemplateMethodModelEx接口
public class TestMethodModel implements TemplateMethodModelEx{
    @Override
    public Object exec(List list) throws TemplateModelException {
        return list.toString();
    }
}

b. 引入方法并使用

<#assign md= "net.lgpage.ant.test.TestMethodModel"?new()> 
${md('1',' 2')}

Freemarker任意获取java返回值

定义一个需要被调用方法的类(自创类似Spring中的controller的东西)

@PathRedirect("test")
public class FreemarkerAction {
    
    public String hello(){
        return "hello";
    }
    @PathRedirect("/xixi")
    public String hehe(){
        return "hello";
    }
    @PathRedirect("/abc/{id}")
    public String hehe(String id,String name,Admin admin){
        if(admin == null)return "hello:"+id;
            System.out.println("终于成功了"+id+",还传了名字"+name+",还给了个对象"+admin.getEmail());
        return "hello:"+id;
    }
}

定义InvokeMethod类

public class InvokeMethod implements TemplateMethodModelEx {
    @Override
    public Object exec(List list) throws TemplateModelException {
        String str = FreeMarkerModelUtil.parse(list.get(0), String.class);
        /*
         * 从ftl文件获取参数
         */
        Object objs[] = new Object[list.size() - 1];
        for (int i = 1; i < list.size(); i++) {
            objs[i - 1] = FreeMarkerModelUtil.parse(list.get(i));
        }
        /*
         * 方法转发核心类(请根据需要自行书写)
         */
        MethodDispatcher d = new MethodDispatcher();
        d.methodManager.putMethod(FreemarkerAction.class);//初始化该类需要被调用的方法
        Object obj = null;
        try {
            obj = d.invoke(str, objs);
            return obj;
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }
}

引入已经定义好的invokeMethod类

<#assign invoke= "net.lgpage.freemarker.method.InvokeMethod"?new()> 
${invoke('test/abc/2','lg')}   //该行代码效果会去调用FreemarkerAction类中hehe(String id,String name,Admin admin)方法,最终结果显示hello:2
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容