模板引擎Freemarker基础知识

Freemarker是什么

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。

常用的java模板引擎还有 Jsp、Freemarker、Thymeleaf 、Velocity 等。

freemarker并不关心数据的来源,只是根据模板的内容,将数据模型在模板中显示并输出文件(通常为html,也可以生成其它格式的文本文件)

freemarker作为springmvc一种视图格式,默认情况下SpringMVC支持freemarker视图格式。

FreeMarker 基础指令

map即为freemarker静态化所需要的数据模型

List指令

1、注释,即:<#‐‐被注释的内容‐‐>

2、插值(Interpolation):即 ${…} 部分,freemarker会用真实的值替换 ${…} 中的内容

3、FTL指令:和HTML标记类似,名字前加#予以区分,Freemarker会解析标签中的表达式或逻辑。例如:<#list stuMap?keys as k> ,就是获取stuMap中的所有的key作为一个list集合,然后取list集合中的一个key赋值给k.

4、文本,仅文本信息,这些不是freemarker的注释、插值、FTL指令的内容会被freemarker忽略解析,直接输出内容。

解释Demo:

<#list stus as stu>
        <tr>
            <td>${stu_index + 1}</td>
            <td>${stu.name}</td>
            <td>${stu.age}</td>
            <td>${stu.mondy}</td>
        </tr>
    </#list>

其中:
_index:得到循环的下标,使用方法是在stu后边加"_index",它的值是从0开始

遍历Map数据

姓名:${stuMap['stu1'].name}<br/>

或者

姓名:${stuMap.stu1.name}<br/>

其中stuMap是一个map集合,stu1是map集合中的一个元素对象,name是stu1的一个属性,如果采用list集合去遍历的话,第二种方法就不适用了。

if指令

if 指令即判断指令,是常用的FTL指令,freemarker在解析时遇到if会进行判断,条件为真则输出if中间的内容,否则跳过内容不再输出。
例如:

<td <#if stu.name =='小明'>style="background:red;"</#if>>${stu.name}</td>

意思就是如果stu的姓名是小明的话,就加背景色

其它指令

运算符

1、算数运算符 FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , %
2、逻辑运算符 逻辑运算符有如下几个: 逻辑与:&& 逻辑或:|| 逻辑非:! 逻辑运算符只能作用于布尔值,否则将产生错误
3、比较运算符 表达式中支持的比较运算符有如下几个: 1 =或者==:判断两个值是否相等. 2 !=:判断两个值是否不等. 3 >或者gt:判断左边值是否大于右边值 4 >=或者gte:判断左边值是否大于等于右边值 5 <或者lt:判断左边值是否小于右边值 6 <=或者lte:判断左边值是否小于等于右边值
注意: =和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比较,“x”,"x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为 FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)>

空值处理

1、判断某变量是否存在使用 “??” 用法为:variable??,如果该变量存在,返回true,否则返回false
例如:

<#if stus??>
    <#list stus as stu>
     ......    
    </#list>
    </#if>

意思就是:如果stus集合不为空就遍历

2、缺失变量默认值使用 “!” 使用!要以指定一个默认值,当变量为空时显示默认值。
例: ${name!’’}表示如果name为空显示空字符串。
如果是嵌套对象则建议使用()括起来。
例如: ${(stu.bestFriend.name)!’’}表示,如果stu或bestFriend或name为空默认显示空字符串。

内建函数

内建函数语法格式: 变量+?+函数名称
例如:
1、和到某个集合的大小
${集合名?size}
2、日期格式化

显示年月日: ${today?date}
显示时分秒:${today?time}  
显示日期+时间:${today?datetime} <br>       
自定义格式化:  ${today?string("yyyy年MM月")}

3、内建函数c
map.put(“point”, 102920122);
point是数字型,使用${point}会显示这个数字的值,不并每三位使用逗号分隔。
如果不想显示为每三位分隔的数字,可以使用c函数将数字型转成字符串输出
${point?c}
4、将json字符串转成对象
一个例子:
其中用到了 assign标签,assign的作用是定义一个变量。

<#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
<#assign data=text?eval />
开户行:${data.bank}  账号:${data.account}

一般这种语法不会用

入门Demo

要导入的依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

配置文件

server:
  port: 8088 #服务端口
spring:
  application:
    name: test-freemarker #服务名
  freemarker:
    cache: false #关闭模板缓存,及时改及时测
    settings:
      template_update_delay: 0 #检查模板更新延迟时间,例如设置为1秒,就是1秒后检查模板是否更新,设置为0表示立即检查,

模型类

@Data
public class Student {
    private String name;//姓名
    private int age;//年龄
    private Date birthday;//生日日期
    private Float money;//金额
    private List<Student> friends;//朋友
    private Student bestFriend;//最好的朋友
}

创建模板

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf‐8">
    <title>Hello World!</title>
</head>
<body>
Hello ${name}!
<br/>
遍历数据模型中的list学生信息,(数据模型中的名称为stus)
<table>
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>金额</td>
        <td>出生日期</td>
    </tr>
    <#--判断list集合是否为空,为空就不执行-->
    <#if stus??>
        <#list stus as stu>
        <tr>
            <td>${stu_index+1}</td>
            <td <#if stu.name == '小明'>style="background-color: cyan" </#if>>${stu.name}</td>
            <td>${stu.age}</td>
            <td <#if (stu.money > 300)>style="background: red" </#if>>${stu.money}</td>
            <td>${stu.birthday?date}</td>
        </tr>
    </#list>
    </#if>
</table>
<br/>
学生的个数:${stus?size}
<br/>
遍历数据模型中的stuMap(map数据),第一种方法,在中括号中填写map的key;第二种方法,在map后面直接加 "."
<br/>
姓名:${(stuMap['stu1'].name)!''}<br/><#--如果stu1用户存在就显示,否则就显示一个空字符串-->
年龄:${(stuMap['stu1'].age)!''}<br/>
金额:${(stuMap['stu1'].money)!''}<br/>
姓名:${(stuMap.stu1.name)!''}<br/>
遍历map中的key,用list标签,stuMap?key就是一个key列表(是一个list)<br/>
<#list stuMap?keys as k>
    姓名:${stuMap[k].name}<br/>
    年龄:${stuMap[k].age}<br/>
</#list>
<br/>
<#--?c的作用就是去掉每三位数字一个分隔符-->
${point?c}
<br/>
<#assign text="{'bank':'工商银行','account':'101920201920212'}" />
<#--?eval的作用就是把text的json字符串转为Java对象-->
<#assign data=text?eval />
开户行:${data.bank} 账号:${data.account}
</body>
</html>

接口数据

	@RequestMapping("/test1")
    public String test1(Map<String, Object> map){
        //map就是freemarker模板所使用的数据
        map.put("name", "好好学习!");

        Student stu1 = new Student();
        stu1.setName("小明");
        stu1.setAge(18);
        stu1.setMoney(1000.86f);
        stu1.setBirthday(new Date());
        Student stu2 = new Student();
        stu2.setName("小红");
        stu2.setMoney(200.1f);
        stu2.setAge(19);
        stu2.setBirthday(new Date());
        List<Student> friends = new ArrayList<>();
        friends.add(stu1);
        stu2.setFriends(friends);
        stu2.setBestFriend(stu1);
        List<Student> stus = new ArrayList<>();
        stus.add(stu1);
        stus.add(stu2);
        //向数据模型放数据
        map.put("stus",stus);
        //准备map数据
        HashMap<String,Student> stuMap = new HashMap<>();
        stuMap.put("stu1",stu1);
        stuMap.put("stu2",stu2);
        //向数据模型放数据
        map.put("stu1",stu1);
        //向数据模型放数据
        map.put("stuMap",stuMap);

        map.put("point",102920122);

        //返回freemarker模板的位置,基于resources/templates路径的,freemarker会从resources/templates下面找
        return "test1";//这个只能是不带后缀的文件名
    }

使用模板文件静态化

    public void getGenerateTest() throws IOException, TemplateException {
        //获取配置
        Configuration configuration = new Configuration(Configuration.getVersion());

        //获取模板
        //获取模板路径
        String path = this.getClass().getResource("/").getPath();
        configuration.setDirectoryForTemplateLoading(new File(path + "/templates/"));
        //获取模板文件
        Template template = configuration.getTemplate("test1.ftl");

        //获取数据模型
        Map modelMap = getModelMap();
        //静态化,生成html页面
        String templateIntoString = FreeMarkerTemplateUtils.processTemplateIntoString(template, modelMap);
       // System.out.println(templateIntoString);
        InputStream inputStream = IOUtils.toInputStream(templateIntoString);
        FileOutputStream outputStream = new FileOutputStream(new File("D:/else/test.html"));
        IOUtils.copy(inputStream,outputStream);
        //关流
        inputStream.close();
        outputStream.close();

    }

使用模板字符串静态化

public void getGenerateTestByString() throws IOException, TemplateException {
        //获取模板字符串
         String templateString="" +
            "<html>\n" +
            "    <head></head>\n" +
            "    <body>\n" +
            "    名称:${name}\n" +
            "    </body>\n" +
            "</html>";
        //生成模板
        Configuration configuration = new Configuration(Configuration.getVersion());
        //获取模板加载器
        StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
        //把字符串模板放入模板加载器中
        stringTemplateLoader.putTemplate("template", templateString);
        //设置模板加载器
        configuration.setTemplateLoader(stringTemplateLoader);
        //转成模板
        Template template = configuration.getTemplate("template", "utf-8");

        //获取模型数据
        Map modelMap = getModelMap();

        //静态化
        String templateIntoString = FreeMarkerTemplateUtils.processTemplateIntoString(template, modelMap);
        InputStream inputStream = IOUtils.toInputStream(templateIntoString);
        FileOutputStream fileOutputStream = new FileOutputStream(new File("D:/else/test2.html"));
        IOUtils.copy(inputStream, fileOutputStream);
        fileOutputStream.close();
        inputStream.close();

    }
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值