freemarker之快速入门(一)

简介

FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写。

FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序

虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据(如下图)


FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件。

FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应用于非Web应用程序环境。

FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库。

FreeMarker是免费的。

快速案例:

1.导入需要的包到项目中:

<dependencies>
    <!--https://mvnrepository.com/artifact/org.freemarker/freemarker -->
   
<dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.23</version>
    </dependency>
</dependencies>

2.我的项目目录结构:


3.tempalate.ftl内容:

你好,${name },你的性别是:${user.sex },你的年龄是:${user.age },你的账户积分是:${user.integral }

4.java代码:

public static void main(String[] args) throws IOException, TemplateException {
    /*创建和调用配置*/
    Configuration cfg = new Configuration();
    /*设置ftl文件路径指定到上一级文件夹*/
    cfg.setDirectoryForTemplateLoading(new File(FreeMarkerTest.class.getResource("/").getPath() + "ftl"));
    cfg.setObjectWrapper(new DefaultObjectWrapper());
    /*获取或创建模板*/
    Template temp = cfg.getTemplate("template.ftl");
    /*创建数据模型存放数据*/
    Map<String, Object> map = new HashMap<>();
    map.put("name", "rabbit");
    Map<String, Object> user = new HashMap<>();
    user.put("sex", "");
    user.put("age", 18);
    user.put("integral", 200.99D);
    map.put("user", user);
    /*将模板和数据模型合并*/
    Writer out = new OutputStreamWriter(System.out);
    temp.process(map, out);
    out.flush();
}

数据类型:(取值方式和EL表达式类似)

标量类型:布尔值(true/false),数字,字符串,日期

使用 java.lang.String构建字符串。

直接指定字符串值使用单引号或双引号限定。字符串中可以使用转义字符”\"。如果字符串内有大量的特殊字符,则可以在引号的前面加上一个字母r,则字符串内的所有字符都将直接输出。

 

使用 java.lang.Number 来派生数字类型。

数值可以直接输入,不需要引号。FreeMarker不支持科学计数法。

 

使用 java.lang.Boolean 来构建布尔值。

直接使用true或false,不使用引号。

 

使用 java.lang.Date 来构建日期值。

 

容器类型:哈希表,序列和集合三中类型

使用 java.util.List 或 Java 数组来构建序列。

使用 java.util.Map 来构建哈希表。

自定义类型:

使用你自己定义的 bean 类来构建哈希表,bean 中的项和 bean 的属性对应。例如product 中的 price 属性可以用 product.price 来获取。 (bean 的 action也可以通过这种方式拿到,要了解更多可以参看:bean 的包装部分内容)

(root)

|

+- mouse = "Yerri"

     |

     +- age = 12

     |

     +- color = "brown"

例如有个自定义类型数据层级是这样的,获取方式如下:

${mouse} <#-- 用 mouse 作为字符串 -->

${mouse.age} <#-- 用 mouse 作为哈希表 -->

${mouse.color} <#-- 用 mouse 作为哈希表 -->

 

比较运算符:

表达式中支持的比较运算符有如下几种:
1. =(或者==):判断两个值是否相等;
2. !=:判断两个值是否不相等;
注: =和!=可以用作字符串、数值和日期的比较,但两边的数据类型必须相同。而且FreeMarker的比较是精确比较,不会忽略大小写及空格。
3. >(或者gt):大于
4. >=(或者gte):大于等于
5. <(或者lt):小于
6. <=(或者lte):小于等于
注:上面这些比较运算符可以用于数字和日期,但不能用于字符串。大部分时候,使用gt比>有更好的效果,因为FreeMarker会把>解释成标签的结束字符。可以使用括号来避免这种情况,如:<#if (x>y)>。

逻辑运算符:

1. &&:逻辑与;
2. ||:逻辑或;
3. !:逻辑非
逻辑运算符只能用于布尔值。

内建函数:

FreeMarker提供了一些内建函数来转换输出,可以在任何变量后紧跟?,?后紧跟内建函数,就可以通过内建函数来转换输出变量。

字符串相关常用的内建函数:
1. html:对字符串进行HTML编码;
2. cap_first:使字符串第一个字母大写;
3. lower_case:将字符串转成小写;
4. upper_case:将字符串转成大写;

 

集合相关常用的内建函数:
1. size:获得集合中元素的个数;

 

数字值相关常用的内建函数:
1. int:取得数字的整数部分。(比如 -1.9?int 就是 -1 )

 

示例:

${test?html}

${test?upper_case?html}

假设字符串 test 存储”Tom & Jerry”,那么输出为:

Tom &amp; Jerry

TOM &amp; JERRY

${seasons?size}

${seasons[1]?cap_first} <#-- left side can by any expression -->

${"horse"?cap_first}

假设 seasons 存储了序列 "winter" ,  "spring" ,  "summer" ,  "autumn" ,那

么上面的输出将会是

4

Spring

Horse

注意 test?upper_case?html ,内嵌函数双重使用, test?upper_case 的

结果是字符串了,但也还可以继续在其后使用 html 内建函数。

 

空值处理运算符:

FreeMarker的变量必须赋值,否则就会抛出异常。而对于FreeMarker来说,null值和不存在的变量是完全一样的,因为FreeMarker无法理解null值。
FreeMarker提供两个运算符来避免空值:
1. !:指定缺失变量的默认值;
2. ??:判断变量是否存在。
!运算符有两种用法:variable!或variable!defaultValue。第一种用法不给变量指定默认值,表明默认值是空字符串、长度为0的集合、或长度为0的Map对象。
使用!运算符指定默认值并不要求默认值的类型和变量类型相同。

测试空值处理:

<#-- ${sss} 没有定义这个变量,会报异常! -->

${sss!} <#--没有定义这个变量,默认值是空字符串! -->

${sss!"abc"} <#--没有定义这个变量,默认值是字符串abc! -->

 

         ??运算符返回布尔值,如:variable??,如果变量存在,返回true,否则返回false。

        

数据类型常见例子:

直接指定值

   字符串: "Foo"或者'Foo'或"It's\"quoted\""或r"C:\raw\string"

   数字:123.45

   布尔值:true, false

   序列:["foo","bar", 123.45], 1..100

   哈希表:{"name":"greenmouse", "price":150}

   检索变量   顶层变量:user

   从哈希表中检索数据:user.name,user[“name”]

   从序列中检索:products[5]

   特殊变量:.main

   字符串操作

   插值(或连接):"Hello${user}!"(或"Free" + "Marker")

   获取一个字符:name[0]

   序列操作

   连接:users +["guest"]

   序列切分:products[10..19]  或  products[5..]

   哈希表操作

   连接:passwords +{"joe":"secret42"}

   算数运算: (x * 1.5 + 10)/ 2 - y % 100

   比较运算:x == y,   x != y,  x < y,   x > y,   x >= y,  x <= y,

x &lt; y,  等等

    逻辑操作:!registered&& (firstVisit || fromEurope)

    内建函数:name?upper_case

    方法调用:repeat("What",3)

   处理不存在的值

   默认值:name!"unknown"  或者(user.name)!"unknown"  或者

name! 或者  (user.name)!

   检测不存在的值:name?? 或者(user.name)??

模板开发语句

最简单的模板是普通  HTML  文件(或者是其他任何文本文件—FreeMarker本身不属于HTML)。当客户端访问页面时,FreeMarker要发送 HTML 代码至客户端浏览器端显示。如果想要页面动起来,就要在 HTML 中放置能被FreeMarker所解析的特殊部分。

 

${…}:FreeMarker将会输出真实的值来替换花括号内的表达式,这样的表达式被称为

interpolations 插值,可以参考第上面示例的内容。

 

   FTL tags 标签(FreeMarker模板的语言标签):FTL 标签和 HTML 标签有一点相似,但是它们是FreeMarker的指令而且是不会直接输出出来的东西。这些标签的使用一般以符号#开头。(用户自定义的 FTL 标签使用@符号来代替#,但这是更高级的主题内容了,后面会详细地讨论)

 

Comments 注释:FreeMarker的注释和 HTML 的注释相似,但是它用<#--和-->来分隔的。任何介于这两个分隔符(包含分隔符本身)之间内容会被FreeMarker忽略,就不会

输出出来了。

 

其他任何不是  FTL  标签,插值或注释的内容将被视为静态文本,这些东西就不会被

FreeMarker所解析,会被按照原样输出出来。

 

   directives指令:就是所指的  FTL  标签。这些指令在  HTML  的标签(如<table>和

</table>)和 HTML 元素(如 table 元素)中的关系是相同的。(如果现在你还不能区

分它们,那么把“FTL 标签”和“指令”看做是同义词即可。)

if指令

root.put("random", new Random().nextInt(100));

------------------------------------------------

if语句测试:

${user}是<#if user=="老高">我们的老师</#if>

------------------------------------------------

if else 语句测试:

<#if num0 gt 18><#--不是使用>,大部分时候,freemarker会把>解释成标签结束! -->

    及格!

<#else>

    不及格!

</#if>

---------------------------------------------------

if else if else语句测试:

<#if random gte 90>

    优秀!

<#elseif random gte 80>

    良好!

<#else>

    一般! 

</#if>

----------------------------------------------------

 

 

list指令

       List list = newArrayList();

       list.add(new Address("中国","北京"));

       list.add(new Address("中国","上海"));

       list.add(new Address("美国","纽约"));

       root.put("lst", list);

测试list指令:

<#list lst as dizhi>

    <b>${dizhi.country}</b><br/>

</#list>

 

控制台打印:

测试list语句:

    <b>中国</b><br/>

    <b>中国</b><br/>

    <b>美国</b><br/>

include指令

增加被包含文件,放于ftl目录下:

 

include.ftl文件内容:

${msg }

 

template.ftl内容修改如下:

<#include "include.ftl">

你好,${name },你的性别是:${user.sex },你的年龄是:${user.age },你的账户积分是:${user.integral }

 

修改代码如下:

public static void main(String[] args) throws IOException, TemplateException {
    /*创建和调用配置*/
    Configuration cfg = new Configuration();
    /*设置ftl文件路径指定到上一级文件夹*/
    cfg.setDirectoryForTemplateLoading(new File(FreeMarkerTest.class.getResource("/").getPath() + "ftl"));
    cfg.setObjectWrapper(new DefaultObjectWrapper());
    /*获取或创建模板*/
    Template temp = cfg.getTemplate("template.ftl");
    /*创建数据模型存放数据*/
    Map<String, Object> map = new HashMap<>();
    map.put("name", "rabbit");
    Map<String, Object> user = new HashMap<>();
    user.put("sex", "");
    user.put("age", 18);
    user.put("integral", 200.99D);
    map.put("user", user);
    /*设置包含include.ftl内容*/
    map.put("msg", "我是被迫包含进来的内容");
    /*将模板和数据模型合并*/
    Writer out = new OutputStreamWriter(System.out);
    temp.process(map, out);
    out.flush();
}

 

 

结果:

我是被迫包含进来的内容

你好,rabbit,你的性别是:男,你的年龄是:18,你的账户积分是:200.99

 

 



展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie
应支付0元
点击重新获取
扫码支付

支付成功即可阅读