Freemarker--学习笔记

目录

前言

二、Freemarker 数据类型

1.布尔类型

2.日期类型

3.数值类型

4.字符串类型

5.sequence类型

6.序列类型(数组、List、Set)

6.1数组

6.2集合

6.1hash

三、Freemarker 常见指令

1.assign 自定义变量指令

2.if elseif else 逻辑判断指令

3.list 遍历指令

4.macro 自定义指令

5.nested 占位符指令

6.import 指令

7.include 包含指令

四、Freemarker 页面静态化

1.定义模板

2.加载模版

3.生成对应的html文件

五、Freemarker 运算符

1.算数运算符

2.逻辑运算符

3. 比较运算符

4.空值运算符

总结

前言

Freemarker学习笔记。

一、Freemarker 概述

FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。是一个Java类库。 FreeMarker 被设计用来生成 HTMLWeb 页面,特别是基于 MVC 模式的应用程序,将视图从业务逻辑中抽离处理,业务中不再包括视图的展示,而是将视图交给 FreeMarker 来输出。虽然 FreeMarker 具有一些编程的能力,但通常由Java 程序准备要显示的数据,由FreeMarker 生成页面,通过模板显示准备的数据(如下图):

FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件。 FreeMarker与容器无关,因为它并不知道HTTP或Servlet。FreeMarker同样可以应用 于非Web应用程序环境。 FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在板中使用JSP标记库。

二、Freemarker 数据类型

1.布尔类型

布尔型:等价于Java中的 boolean 类型,不同的是不能直接输出,可转化为字符串输出。

布尔类型不能在模板中直接使用,需要使用c、string、string('true','false')等方法进行转换。

//设置数据(给模版设置数据)

req.setAttribute("flag",false);

//模版

${flag?c}

${flag?string}

${flag?string('对了','错了')}

2.日期类型

日期型:等价于Java中的 Date 类型,不同的是不能直接输出,需要转换成字符串再输出。

日期类型不能在模板中直接使用,需要使用string('yyyy.MM.dd HH:mm:ss')、date、time、datetime等方法进行转换。

//设置数据(给模版设置数据)

req.setAttribute("date",new Date());

//模版

<#-- 自定义时间输出格式。-->

${date?string('yyyy.MM.dd HH:mm:ss')}

<#--仅日期部分,没有一天当中的时间部分。-->

${date?date}

<#--仅一天当中的时间部分,没有日期部分。-->

${date?time}

<#--日期和时间都在-->

${date?datetime}

3.数值类型

等价于 Java 中的 int,float,double 等数值类型。有三种显示形式:数值型(默认),货币型(string.currency),百分比型(string.percent)。

//设置数据(给模版设置数据)

req.setAttribute("numberId",532930);

req.setAttribute("age",24);

req.setAttribute("avg",0.253);

//模版

<#--将数值转化为字符串类型-->

${numberId?c}

<#--将数值转换为货币类型-->

${age?string.currency}

<#-- 将数值转换为百分百类型-->

${avg?string.percent}

4.字符串类型

等价于Java中的字符串,有很多内置函数。

//设置数据(给模版设置数据)

req.setAttribute("name","陈清零");

//模版

<#--字符串长度-->

${name?length}

<#--提取字符串前两个字符并输出。-->

${name?substring(0,2)}

<#--将字符串转换为小写并输出。-->

${name?lower_case}

<#--将字符串的首字母大写并输出-->

${name?cap_first}

5.sequence类型

FreeMarker 的变量必须赋值,否则就会抛出常。而对于 FreeMarker 来说,null 值和不存在的变量是完全一样的,因为 FreeMarker 无法理解 null 值。

FreeMarker 提供两个运算符来避免空值:1. ! : 指定缺失变量的默认值 ${ value! } : 如果value值为空,则默认值是空字符串 ${ value! "默认值" } : 如果value值为空,则默认值是字符串"默认值"2. ?? : 判断变量是否存在 ${ (value??) ?string } : 如果变量存在,返回 true,否则返回 false

${CD!"CD不存在"}

${(CD??)?string}

6.序列类型(数组、List、Set)

6.1数组

遍历数组:通过list指令输出序列<#list 序列名 as 元素名> ${元素名}

获取序列的长度:${序列名?size} 获取序列元素的下标:${元素名?index} 获取第一个元素:${序列名?first} 获取最后一个元素:${序列名?last}

//设置数据(给模版设置数据)

String[] strs={"java","c++","python","c"};

req.setAttribute("strs",strs);

//模版

<#list strs as item>

下标:${item?index}-课程名称:${item}

数组长度:${strs?size}

第一个元素:${strs?first}

最后一个元素:${strs?last}

6.2集合

遍历集合:通过list指令输出序列<#list 序列名 as 元素名> ${元素名}

倒序输出:序列名?reverse

升序输出:序列名?sort

降序输出:序列名?sort?reverse

//设置数据(给模版设置数据)

List list= Arrays.asList("云南","贵州","四川","重庆");

req.setAttribute("list",list);

//模版

<#list list as item>

${item} -


<#--倒序输出 序列名?reverse-->

倒序输出:

<#list list?reverse as item>

${item}


<#--升序输出 序列名?sort-->

升序输出:

<#list list?sort as item>

${item}


<#--降序输出 序列名?sort?reverse-->

降序输出:

<#list list?sort?reverse as item>

${item}

遍历Java对象

//设置数据(给模版设置数据)

//java 对象

List stu= new ArrayList<>();

stu.add(new Student(1,"张三",18,"北京市","12345678901","计算机网络1班"));

stu.add(new Student(2,"李四",16,"北京市","12345678901","人工智能1班"));

stu.add(new Student(3,"王五",24,"北京市","12345678901","大数据网络1班"));

req.setAttribute("stu",stu);

//模版

<#--遍历java对象-->

<#list stu?sort_by("age")?sort?reverse as student>

  • 学号:${student.id}

    姓名:${student.name}

    年龄:${student.age}

    地址:${student.address}

    手机号:${student.phone}

    班级:${student.className}

  • 6.1hash

    遍历hash:

    法一:key遍历输出<#list 序列名?keys as key> ${key} -- ${hash[key]}

    法二:value遍历输出

    <#list 序列名?values as value> ${value}

    //设置模版(给模版设置数据)

    Map map = new HashMap<>();

    map.put("id",1);

    map.put("name","塔斯汀");

    map.put("age",18);

    map.put("sex","男");

    req.setAttribute("ttmap",map);

    //模版

    <#-- 法一 -->

    <#list ttmap?keys as key >

    ${key}:${ttmap[key]}


    <#-- 法二 -->

    <#list ttmap?values as value >

    ${value}


    <#-- 法三 -->

    <#list ttmap as key,value>

    ${key}:${value}

    三、Freemarker 常见指令

    1.assign 自定义变量指令

    语法: <#assign 变量名=值> <#assign 变量名=值 变量名=值>(定义多个变量)

    <#assign name="张三" age=18 love=["红","蓝","黄"]>

    ${name}-${age}

    <#list love as item>

    ${item}

    2.if elseif else 逻辑判断指令

    格式: <#if condition> <#elseif condition2> <#elseif condition3> <#else> 注: 1.condition,condition2等,将被计算成布尔值的表达式。 2.elseif 和 else 指令 是可选的。

    <#assign score=80>

    <#if score<60>

    考试不及格

    <#elseif score gt 60 && score lt 80>

    考试及格

    <#else>

    考试优秀

    3.list 遍历指令

    格式1: <#list sequence as item> 格式2: <#list sequence as item> <#else>当没有选项时,执行else指令 注: 1.else 部分是可选的 2.sequence: 想要迭代的项,可以是序列或集合的表达式 3.item: 循环变量 的名称 4.当没有迭代项时,才使用 else 指令,可以输出一些特殊的内容而不只是空在那里。

    <#assign list1=[1,2,3,4,5,6,7,8,9,10]>

    <#assign list2=["张三","李四","王五","赵六","钱七","马八","黄九","周十"]>

    <#assign list3=[]>

    <#list list1 as item>

    ${item}、


    <#-- 判断数据不为空,再执行遍历。当序列没有数值时,使用默认信息-->

    <#if list7??>

    <#list list7 as item>

    ${item}

    <#else>

    没有数据遍历list2: 

    <#list list2 as item>

    ${item}

    4.macro 自定义指令

    macro自定义指令(宏) 1.基本使用 格式: <#macro 指令名> 指令内容 使用: <@指令名> 2.有参数的自定义指令 格式: <#macro 指令名 参数名1 参数名2> 指令内容 使用: <@指令名 参数名1=参数值1 参数名2=参数值2> 注 1.指令可以被多次使用。 2.自定义指令中可以包含字符串,也可包含内置指令-->

    //用法一 自定义无参数指令

    <#macro patent>

    © 1999–2015 The FreeMarker Project. All rights reserved.

    <#macro patent02>

    嵌套自定义指令<@patent/>

    <@patent/>

    <@patent02/>

    //用法二 自定义有参指令

    <#macro customerInformation name age ddress>

    姓名:${name}

    年龄:${age}

    地址:${ddress}

    <@customerInformation name="李四" age="19" ddress="北京市" />

    <#--九九乘法表-->

    <#macro jj>

    <#list 1..9 as i>

    <#list 1..i as j>

    ${j} * ${i} = ${i*j}  


    <@jj/>

    5.nested 占位符指令

    nested 相当于占位符,一般结合macro指令一起使用。可以将自定义指令中的内容通过nested指令占位,当使用自定义指令时,会将占位内容显示。

    <#macro text>

    问君何能尔<#nested>

    <@text/>

    <@text>心远地自偏

    6.import 指令

    import 指令用于导入其他模板文件,并使用导入的模板文件中定义的变量。 import 指令的格式: <#import "模板文件路径" as 指令名> 使用: <@指令名.变量名/>

    // f04.ftl

    <#--九九乘法表-->

    <#macro jj>

    <#list 1..9 as i>

    <#list 1..i as j>

    ${j} * ${i} = ${i*j}  


    <@jj/>

    //f03.ftl

    <#import "/template/f04.ftl" as f04>

    <@f04.jj/>

    7.include 包含指令

    可以使用 include 指令在你的模板中插入另外一个 FreeMarker 模板文件。 被包含模板的输出格式是在include 标签出现的位置插入的。 被包含的文件和包含它的模板共享变量,就像是被复制粘贴进去的一样。

    <#include "f04.ftl" >

    四、Freemarker 页面静态化

    通过上述介绍可知 Freemarker 是一种基于模板的、用来生成输出文本的通用工具,所以我们必须要定制符合自己业务的模板,然后生成自己的 html页面。

    Freemarker 是通过freemarker.template.Configuration 这个对象对模板进行加载的(它也处理创建和缓存预解析模板的工作),然后我们通过 getTemplate 方法获得你想要的模板,有一点要记住freemarker.template.Configuration 在你整个应用必须保证唯一实例。

    应用场景:页面上的数据基本不会变,变化频率不高。例如购物平台上的商品分类、新闻发布后的内容等。

    1.定义模板

    news.ftl

    <#--新闻标题-->

    ${title}

    <#--新闻来源 发布时间-->

    <#--本报记者-->

    本报记者 ${author}

    新闻来源:${source}  发布时间:${date?string('yyyy.MM.dd HH:mm:ss')}

    <#--新闻内容-->

    ${content}

    2.加载模版

    //实例化模版对象

    Configuration con= new Configuration();

    //设置加载模版的上下文 以及加载模版的路径 (模版存放路径)

    con.setServletContextForTemplateLoading(this.getServletContext(),"template");

    //设置模版的 编码格式

    con.setDefaultEncoding("utf-8");

    //加载模版文件 获取模版对象

    Template template = con.getTemplate("news.ftl");

    //设置数据模型

    Map map = new HashMap<>();

    map.put("title","家门口有了优质中医药服务(健康焦点)");

    map.put("content","今年9月,国家中医药管理局等5部门联合发布《关于加快推进县级中医医院高质量发展的意见》(以下简称《意见》),提出到2025年,80%以上县级中医医院力争达到二级甲等以上中医医院水平,500所左右县级中医医院力争达到三级中医医院水平。\n"+"据统计,目前我国县级中医医院有2000多家,约占公办中医医院的3/4,其诊疗量约占县域中医医疗机构总诊疗量的70%。近年来,我国县级中医医院建设取得一定进展,基础设施条件有所改善,管理水平、人员素质有了进一步提高。深入落实《意见》要求,各地正在努力探索,加快推进县级中医医院高质量发展。\n" +"医疗资源沉下去——\n" + "破解基层医疗服务难题,推进县级中医医院医共体建设");

    map.put("author","杨xx 游 x 窦xx");

    map.put("source","xx日报");

    map.put("date",new Date());

    3.生成对应的html文件

    //获取项目的根目录

    String path = req.getServletContext().getRealPath("/");

    //设置html文件存放的路径

    File htmlFile = new File(path+"/html");

    //判断文件(目录)是否存在

    if (!htmlFile.exists()){

    //如果不存在就创建

    htmlFile.mkdir();

    }

    //得到生成的文件名(生成随机不重复的文件名)

    String fileName = System.currentTimeMillis()+".html";

    //创建html文件

    File file = new File(htmlFile,fileName);

    //获取文件输出流

    FileWriter fileWriter = new FileWriter(file);

    //生成html(将数据模型填充到模版 中)

    try {

    template.process(map, fileWriter);

    } catch (TemplateException e) {

    e.printStackTrace();

    }finally {

    //关闭资源

    fileWriter.flush();

    fileWriter.close();

    }

    五、Freemarker 运算符

    1.算数运算符

    <#-- +、-、*、/、%-->

    <#assign a=3 b=5>

    ${a} + ${b} = ${a+b}

    ${a} - ${b} = ${a-b}

    ${a} * ${b} = ${a*b}

    ${a} / ${b} = ${a/b}

    ${a} % ${b} = ${a%b}

    2.逻辑运算符

    <#--&&、||、! -->

    <#assign a=3 b=5 c=15>

    <#if a*b=c && a

    &&

    <#if a==b || a

    ||

    <#if a!=b >

    !

    3. 比较运算符

    gt : 大于号,推荐使用 gtlt : 小于号,推荐使用 ltgte : 大于等于,推荐是用 gtelte : 小于等于,推荐使用 lte == : 等于 != : 不等于

    <#assign a=3 b=5 c=15>

    <#if c gt b >

    ${c} 大于 ${b}

    <#if a lt b>

    ${a} 小于 ${b}

    <#if a*b gte c>

    ${a} 乘 ${b} 大于等于 ${c}

    <#if a*b lte c>

    ${a} 乘 ${b} 小于等于 ${c}

    4.空值运算符

    空值运算符 1. ?? : 判断是否为空,返回布尔类型 如果不为空返回 false,如果为空返回 true,不能直接输出 ${(name??)?string} 2. ! : 设置默认值,如果为空,则设置默认值 1.设置默认为空字符串: ${name!} 2.设置指定默认值 ${name!'张三'}

    <#assign name="">

    ${(name??)?string}

    ${(name2??)?string}

    ${(name2??)?string('存在','不存在')}

    ${name2!"陈清零"}

    总结

    学习总结笔记。

    [an error occurred while processing the directive]
    Copyright © 2088 迷你世界杯_竞猜世界杯 - xhfzmy.com All Rights Reserved.
    友情链接