freemarker语法和在java中应用

33 篇文章 2 订阅
17 篇文章 0 订阅

翻笔记翻出来的。


在线测试
https://try.freemarker.apache.org/

基础

freemarker是一个Java编写的模板引擎,它基于模板产生文本,输出可以是html、XML、JSP和Java等,只要给与特定的模板。

使用场景:网页静态化。即使用freemaker生成网页

网页静态化技术和缓存技术都是为了减轻数据库的访问压力,但缓存适合小规模数据,网页静态化适合大规模且相对变化不太频繁的数据。网页静态化有利于SEO(搜索引擎优化,即搜索引擎搜静态网页更快),那么可以使用nginx来部署,有利于高并发。

freemaker文件后缀为ftl,内容包括:

  1. 插值interpolation:${表达式} freemaker会用真实值代替表达式,这个表达式就是插值
  2. FTL标签:以#开头(用户自定义的用@开头),不会在输出中打印
  3. 注释:以<#–和–>标识,不会在输出中打印(html中注释会显示在生成的源代码中,freemaker的注释不会显示在生成的源码中)
  4. 其他都是静态文本,会原样输出

简单示例

  1. 首先在pom文件中引入依赖
<dependency>
	<groupId>org.freemarker</groupId>
	<artifactId>freemarker</artifactId>
</dependency>
  1. ftl文件
<html>
<head>
	<meta charset="utf-8">
	<title>freemaker测试</title>
</head>
<body>
<#--我是freemaker注释-->
<!--我是html注释-->
<h1>${name}, 你好!</h1>
<p>this is ${message} for you.</p>
</body>
</html>
  1. 装数据
package com.example.demo;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class TestFM {
	void writeTemplate() throws Exception {
		Configuration co = new Configuration(Configuration.getVersion());
		// 模板文件所在的文件夹夹路径
		co.setDirectoryForTemplateLoading(new File("F:/eclipse/workspace/helloworld/demo-1/src/main/java/com/example/demo"));
		// 设置字符集
		co.setDefaultEncoding("utf-8");
		// 模板文件的名称
		Template template = co.getTemplate("test.ftl");
		// 使用map存数据
		Map map = new HashMap();
		map.put("name", "张老三");
		map.put("message", "欢迎欢迎");
		// 获取当前项目的根
		String rootDir = System.getProperty("user.dir");
		// 生成文件的路径和名称
		Writer out = new FileWriter(new File(rootDir + "/src/main/java/com/example/demo/test.html"));
		// 用process函数实现真正的填充
		template.process(map, out);
		// 关闭,不然以上数据还在内存中,需要refresh才能持久化到磁盘
		out.close();
	}
}
  1. 这样就能生成html文件了,同名test.html内容如下:内容已经填充完毕,freemarker的注释没有出现
<html>
<head>
	<meta charset="utf-8">
	<title>freemaker测试</title>
</head>
<body>
<!--我是html注释-->
<h1>张老三, 你好!</h1>
<p>this is 欢迎欢迎 for you.</p>
</body>
</html>

标签

assign

定义变量,可以是简单类型,即直接给变量赋值;也可以是对象类型。
<#assign linkman="张三">…联系人:${linkman}

对象类型用字典定义,使用时用点号
<#assign info={"mobile":"1314520",'address':'中国台湾省'} >
电话:${info.mobile}
地址:${info.address}

include

模板嵌套
<#include "head.ftl">

if

如果if的条件满足,那么两框之间的内容就会显示
Welcome ${user}<#if user == "pxy">, our beloved leader</#if>!

用=或==都可以

<#if success==true>
你已通过实名认证
<#else>
你未通过实名认证
</#if>

list

在java代码中,创建列表,里面每一项都带名字和价格

Map map = new HashMap();
List goodsList=new ArrayList();
Map goods1=new HashMap();
goods1.put("name", "苹果");
goods1.put("price", 5.8);
Map goods2=new HashMap();
goods2.put("name", "香蕉");
goods2.put("price", 2.5);
Map goods3=new HashMap();
goods3.put("name", "橘子");
goods3.put("price", 3.2);
goodsList.add(goods1);
goodsList.add(goods2);
goodsList.add(goods3);
map.put("goodsList", goodsList);

ftl文件中,写:

<#list goodsList as goods>
${goods_index}商品名称: ${goods.name} 价格: ${goods.price} <br>
</#list>

则产生的html中显示为:

0商品名称: 苹果 价格: 5.8 <br>
1商品名称: 香蕉 价格: 2.5 <br>
2商品名称: 橘子 价格: 3.2 <br>

内建函数

格式:变量+?+函数名称
这些内建函数是属于freemarker的,可以应用链式操作。如果函数需要参数,就在后面加括号,给参数,如user?starts_with("J") 根据 user 的首字母是否是 “J” 返回布尔值true或false。不需要参数的,可以省略括号,如user?upper_case?html 会先转换用户名到大写形式,之后再进行HTML转义。
参考:http://freemarker.foofun.cn/ref_builtins.html

举例:
ftl中写:
总数: ${goodsList?size}
产生的html中显示:
总数: 3

举例:将json字符串转为对象

<#assign text="{'bank':'工商银行','account':'101019xxxx1920212'}" />  
<#-- 这里定义的是一个json字符串{}是被""包裹在 -->
<#assign data=text?eval />   
<#-- 通过eval函数将json字符串text转换成对象,赋值给变量data,就可以通过data取值了 -->

开户行: ${data.bank} 账号: ${data.account}

举例:日期格式化
java中写:
map.put("today",new Date());
ftl中写:

当前日期: ${today?date} <br>
当前时间: ${today?time} <br>
当前日期+时间: ${today?datetime} <br>
日期格式化: ${today?string("yyyy 年 MM 月")}

则html中显示:

当前日期: 2020-2-11 <br>
当前时间: 15:55:18 <br>
当前日期+时间: 2020-2-11 15:55:18 <br>
日期格式化: 2020 年 02 月

举例:数字的显示问题
前例中,如果map.put("number", 555555.8),那么由于是数字,以${number}取值时,生成的html会自动变为555,555.8。如果不希望自动分割,那么要用${number?c}

空值问题

如果在模板中使用的变量,没有在代码中赋值,则运行时会抛出异常。为了避免:

  1. 用??判断变量是否存在
<#if aaa??>
aaa 变量存在
<#else>
aaa 变量不存在
</#if>

2.直接转换null:当aaa不存在时显示ppp
${aaa!'ppp'}

关于多级访问的变量,比如 animals.python.price, 书写代码:animals.python.price!0 当且仅当 animals.python 永远存在, 而仅仅最后一个子变量 price 可能不存在时是正确的 (这种情况下我们假设价格是 0)。

如果 animals 或 python 不存在, 那么模板处理过程将会以"未定义的变量"错误而停止。为了防止这种情况的发生, 可以如下这样来编写代码 (animals.python.price)!0。 这种情况就是说 animals 或 python 不存在时, 表达式的结果是 0。对于 ?? 也是同样用来的处理这种逻辑的; 将 animals.python.price?? 对比 (animals.python.price)??来看。

运算符

  1. 算数运算符:±*/%
  2. 逻辑运算符:&& || ! 只能作用于布尔值
  3. 比较运算符:=或== != >或gt >=或gte <或lt <=或lte
    其中==和!=可以用于字符串、数值和日期,但是两侧必须是相同类型。其他不可用于字符串建议用gt等代替>避免被当成标签。或者用括号,如<#if(x>y)>
  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值