4年前,我一直都在QQ空间发布学习日志,想想那是自己真傻,为什么会选择在QQ空间发布呢,太不专业了,开始鄙视自己了。这是一篇有关FreeMarker的学习笔记。
晚上回家不知道干嘛,就随便看了下FreeMaker开发指南这本电子书,大概看了一个多小时。不知道是文档写的太通俗了,还是我理解能力好,很快就上手写了些笔记和测试demo,觉得有必要做个记录。
也许你会问FreeMaker是什么,它是干嘛用的?我就不去网上copy那些废话了,我的理解是它是一个基于Java的模版视图层组件,跟jsp一个性质,但是远比jsp强大。它有自己的指令和数据类型,虽然jsp也有jsp tag,但是FreeMaker的强大关键在于它的macro宏,而且用户还能自定义宏,什么叫宏?我的理解是,其实就是对模版代码片段的一个封装,类似于Java里的方法一个概念吧,个人观点哈!宏就是为了模版代码的重用。下面是我学习过程做的一些笔记,主要是一些指令,自己写些demo测试下就明白了,有过其他编程语言的,学它应该不难。
FreeMaker常用指令:
条件判断
<#if 表达式>
<#elseif>
<#else>
</#if>
FreeMaker常用指令:
条件判断
<#if 表达式>
<#elseif>
<#else>
</#if>
<#switch value>
<#case refValue1>
<#break>
<#case refValue2>
<#break>
<#case refValueN>
<#break>
<#default>
</#switch>
<#case refValue1>
<#break>
<#case refValue2>
<#break>
<#case refValueN>
<#break>
<#default>
</#switch>
集合遍历
<#list students as student>
<#list students as student>
引入外部文件
<#include "/top.html">
<#import "/lib/my_test.ftl" as my>
include与import指令的区别:import导入方式有命名空间的概念,
比如这里的my就是命名空间,然后就可以通过my命名空间访问外部的宏
<#include "/top.html">
<#import "/lib/my_test.ftl" as my>
include与import指令的区别:import导入方式有命名空间的概念,
比如这里的my就是命名空间,然后就可以通过my命名空间访问外部的宏
HTML代码原样输出
<#escape x as x?html>
<#noescape></#noescape>刚好相反
<#escape x as x?html>
<#noescape></#noescape>刚好相反
compress指令:移除缩进、空行和重复的空格/制表符
<#compress></#compress>
<#compress></#compress>
!后面紧跟的是变量的默认值
${user!"Anonymous"}
${user!"Anonymous"}
??跟在变量后面,用于判断一个变量是否存在
<#if user??>
?if_exists 也是用于判断变量是否存在,如user.name?if_exists
<#if user??>
?if_exists 也是用于判断变量是否存在,如user.name?if_exists
?default(defaultValue) 用于设置变量默认值
!表达式 也可以用于设置默认值。如user.name!"Tom"
!表达式 也可以用于设置默认值。如user.name!"Tom"
这里的()不能省,
若animals或python不存在,
则会报“未定义的变量”异常
(animals.python.price)!0
若animals或python不存在,
则会报“未定义的变量”异常
(animals.python.price)!0
FreeMaker数据类型:
字符串 布尔值 数值 日期 序列 哈希值
字符串 布尔值 数值 日期 序列 哈希值
FreeMaker内置函数:
String:
cap_first 首字母转换成大写
upper_case 转换成大写
lower_case 转换成小写
length 返回字符串长度
substring(start,end) 字符串截取,前闭后开区间
index_of(substring,start) 返回找到子串的第一个字符的索引,不存在返回-1
contains(str) 返回是否包含指定子串
number 将字符串转换为数字
replace(a,b) 将字符串中a替换成b
split(prefix) 将字符串那指定的分隔符分割成一个数组
trim 去除首尾空格
date("yyyy-MM-dd") 将字符串转换成指定格式日期
ends_with(str) 判断是否以指定子串结尾
html 字符串中所有的特殊HTML字符使用实体引用来代替,如< <
String:
cap_first 首字母转换成大写
upper_case 转换成大写
lower_case 转换成小写
length 返回字符串长度
substring(start,end) 字符串截取,前闭后开区间
index_of(substring,start) 返回找到子串的第一个字符的索引,不存在返回-1
contains(str) 返回是否包含指定子串
number 将字符串转换为数字
replace(a,b) 将字符串中a替换成b
split(prefix) 将字符串那指定的分隔符分割成一个数组
trim 去除首尾空格
date("yyyy-MM-dd") 将字符串转换成指定格式日期
ends_with(str) 判断是否以指定子串结尾
html 字符串中所有的特殊HTML字符使用实体引用来代替,如< <
数字:
c 将数字转成字符串
string.number 数字转成字符串
string.currency 数字转换成货币形式字符串,如¥20.00
string. percent 数字转换成百分比,如20%
int 获取数字的整数部分
c 将数字转成字符串
string.number 数字转成字符串
string.currency 数字转换成货币形式字符串,如¥20.00
string. percent 数字转换成百分比,如20%
int 获取数字的整数部分
Hash(哈希类似于Java里的Map):
keys 返回hash的所有key,返回类型为序列(序列相当于数组的概念)
values 返回hash的所有value,返回类型为序列
keys 返回hash的所有key,返回类型为序列(序列相当于数组的概念)
values 返回hash的所有value,返回类型为序列
Sequence(序列):
first 返回序列里的第一个元素
last 返回最后一个元素
reverse 将当前序列倒序排列
size 返回序列元素个数
sort 将序列的元素转换成字符串后排序
sort_by(property) 将序列按序列中对象的属性property进行排序
两个序列可以通过+合并,
sequence[5..9] sequence[5..] 序列截取,全闭区间
first 返回序列里的第一个元素
last 返回最后一个元素
reverse 将当前序列倒序排列
size 返回序列元素个数
sort 将序列的元素转换成字符串后排序
sort_by(property) 将序列按序列中对象的属性property进行排序
两个序列可以通过+合并,
sequence[5..9] sequence[5..] 序列截取,全闭区间
布尔值:
string 将布尔值转换成字符串
如true?string 结果"true"
string[("男", "女")]
string 将布尔值转换成字符串
如true?string 结果"true"
string[("男", "女")]
宏:(类似于java里的方法,用于重用模版代码片段)
<#macro 宏名称 param1 param2...>
宏定义体...
</#macro>
宏调用:<@宏名称 param1="value1" param2="value2";a,b,c></@宏名称>或</@宏名称>
这里的a,b,c是循环变量
<#macro 宏名称 param1 param2...>
宏定义体...
</#macro>
宏调用:<@宏名称 param1="value1" param2="value2";a,b,c></@宏名称>或</@宏名称>
这里的a,b,c是循环变量
掌握了上面那些指令,就可以开始动手写些demo了。首先需要明确一点的是,FreeMaker是一个模版引擎,负责将ftl模版解析并输出成规定的格式文本文件或以流的形式传输,它与web容器无关,或者说它不依赖于Web环境。首先看看,在Java Project环境下如果使用它:
首先新建个Java Project工程,new个测试类FreeMakerTest,首先FreeMaker模版需要一个FreeMaker模版管理器Configuration对象,该对象有个方法setDirectoryForTemplateLoading用于设置管理器默认以哪个目录作为根目录去加载模版文件,由于没有web环境,所以只能通过类加载器去获取当前类所处路径,然后相对当前类去确定模版文件路径,具体到代码如下:
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(
new File(
FreeMakerTest.class.getClassLoader().getResource("com/yida/config/freemaker/").toURI()
)
);
cfg.setObjectWrapper(new DefaultObjectWrapper());
由于Configuration 一般只需初始化一次即可,所以在非web环境中可以考虑实现成单实例,,如果是在web项目中,则可以把Configuration初始化放到Servlet的init方法里,这里我就懒得去实现了。然后就是获取模版、准备数据以及输出流输出解析内容,最后根据FreeMaker的模版+数据 = 输出的设计理念调用process执行即可,so easy!
//获取模版
Template template = cfg.getTemplate("test.ftl");
//创建数据模型
Map root = new HashMap();
root.put("user", "Big Joe");
Map latest = new HashMap();
root.put("latestProduct", latest);
latest.put("url", "products/greenmouse.html");
latest.put("name", "green mouse");
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();
然后建个ftl模版文件测试下效果,我test。ftl文件是放在com.yida.config.freemaker目录下,内容编辑如下:
${user}-${latestProduct.url}-${latestProduct.name}
直接运行FreeMakerTest java类,如果看到输出内容,则恭喜测试成功!下面开始试着写个web环境下的demo,GO!
首先也是新建个web项目,导入FreeMaker.jar,这个随便google下到处有下载。然后建个servlet测试类,init方法里初始化Configuration 管理器,然后doGet里通过configuration对象初始化web上下文,cfg.setServletContextForTemplateLoading方法接收两个参数,第一个参数就是servletcontext上下文,第二个参数是个String类型,用于设置加载template时的相对路径,如果第二个参数为null,则默认是相对webroot去加载ftl文件,假如你在webroot下有个ftl文件夹,该文件夹下存放的是ftl模版文件,那你cfg.getTemplate时,路径就是这样ftl/???.ftl,如果你设置相对路径是ftl,那这时候直接getTemplate里指定???.ftl即可。然后就是准备数据,接下来就是输出流的获取,只要是OutPutStream即可,当然你也可以给它一个FileOutPutStream,那样它就不是输出到浏览器显示了,而是写入到文件了,最后就是页面跳转到ftl文件,servlet中或者Action中输出流的获取就不多说了吧,其他的步骤大致相同,然后你注册下servlet类,最后新建个ftl模版文件测试下。
Template template = cfg.getTemplate("test.ftl");
//创建数据模型
Map root = new HashMap();
root.put("user", "Big Joe");
Map latest = new HashMap();
root.put("latestProduct", latest);
latest.put("url", "products/greenmouse.html");
latest.put("name", "green mouse");
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();
然后建个ftl模版文件测试下效果,我test。ftl文件是放在com.yida.config.freemaker目录下,内容编辑如下:
${user}-${latestProduct.url}-${latestProduct.name}
直接运行FreeMakerTest java类,如果看到输出内容,则恭喜测试成功!下面开始试着写个web环境下的demo,GO!
首先也是新建个web项目,导入FreeMaker.jar,这个随便google下到处有下载。然后建个servlet测试类,init方法里初始化Configuration 管理器,然后doGet里通过configuration对象初始化web上下文,cfg.setServletContextForTemplateLoading方法接收两个参数,第一个参数就是servletcontext上下文,第二个参数是个String类型,用于设置加载template时的相对路径,如果第二个参数为null,则默认是相对webroot去加载ftl文件,假如你在webroot下有个ftl文件夹,该文件夹下存放的是ftl模版文件,那你cfg.getTemplate时,路径就是这样ftl/???.ftl,如果你设置相对路径是ftl,那这时候直接getTemplate里指定???.ftl即可。然后就是准备数据,接下来就是输出流的获取,只要是OutPutStream即可,当然你也可以给它一个FileOutPutStream,那样它就不是输出到浏览器显示了,而是写入到文件了,最后就是页面跳转到ftl文件,servlet中或者Action中输出流的获取就不多说了吧,其他的步骤大致相同,然后你注册下servlet类,最后新建个ftl模版文件测试下。
上面介绍的是在web环境下用硬编码的形式使用FreeMaker来帮组我们解析模版并输出,其实FreeMaker已经帮我们实现好了一个Servlet工具类,我们只需注册它,然后我们访问任何ftl文件,都会经过它过滤处理即可,不用我们自己编码处理,省事很多。具体web.xml里配置看如下代码:
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>
freemarker.ext.servlet.FreemarkerServlet
</servlet-class>
<init-param>
<param-name>NoCache</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>ContentType</param-name>
<param-value>text/html</param-value>
</init-param>
<!-- FreeMarker settings: -->
<init-param>
<param-name>default_encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>locale</param-name>
<param-value>zh_CN</param-value>
</init-param>
<init-param>
<param-name>number_format</param-name>
<param-value>0.##########</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
上面红色标注部分是重点,然后再写个Servlet测试类试验下,doGet里再也不用什么初始化模版管理器,获取模版、输出流等繁琐的工作了,只需通过request对象setAttribute往request作用域存放数据,然后request.getDispatcher进行页面跳转到ftl模版,这里不能使用redirect方式跳转,为什么我就不解释了吧,redirect的话request作用域的数据就丢失了,跳转到ftl就没意义咯。最后建个ftl测试,OK,若看到理想输出,则表明测试成功!
下面介绍如何将FreeMaker与Struts2整合在一起,首先导入Struts2所需的jar和FreeMaker类库,然后web.xml里struts2注册。准备工作完毕后,那就new个测试类TestAction类别忘了继承下ActionSuport,写个测试方法test:
public class TestAction extends ActionSupport{
public String test(){
((HttpServletRequest)ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST))
.setAttribute("test", "Hello World!");
return "test";
}
}
然后struts.xml里配置下页面导航,这里需要注意的是result type需要写成freemarker,注意是freemarker不是freemaker,我搞不清楚为什么Struts会犯这种弱智错误,弄的我调试N久,无语中......不清楚的请参看我下面配置代码:
<action name="testAction" class="testAction">
<result type="freemarker" name="test">ftl/test.ftl</result>
</action>
test.ftl里很简单,就${test},如果没写错的话,最后访问Action的test方法浏览器会输出Hello World!
是不是觉得ftl模版写的太简单了,那就试着ftl里自定义个宏,说做就做,再建个ftl模版,内容编辑如下:
<#macro test name>
Hello ${name}!
</#macro>
<@test name="张三"/>
内容很简单,就是输出了个hello加上一个参数name值,然后本模版里调用宏,action测试类不需要更改,只需更改action导航配置,使它跳转新建的ftl模版即可。
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>
freemarker.ext.servlet.FreemarkerServlet
</servlet-class>
<init-param>
<param-name>NoCache</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>ContentType</param-name>
<param-value>text/html</param-value>
</init-param>
<!-- FreeMarker settings: -->
<init-param>
<param-name>default_encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>locale</param-name>
<param-value>zh_CN</param-value>
</init-param>
<init-param>
<param-name>number_format</param-name>
<param-value>0.##########</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
上面红色标注部分是重点,然后再写个Servlet测试类试验下,doGet里再也不用什么初始化模版管理器,获取模版、输出流等繁琐的工作了,只需通过request对象setAttribute往request作用域存放数据,然后request.getDispatcher进行页面跳转到ftl模版,这里不能使用redirect方式跳转,为什么我就不解释了吧,redirect的话request作用域的数据就丢失了,跳转到ftl就没意义咯。最后建个ftl测试,OK,若看到理想输出,则表明测试成功!
下面介绍如何将FreeMaker与Struts2整合在一起,首先导入Struts2所需的jar和FreeMaker类库,然后web.xml里struts2注册。准备工作完毕后,那就new个测试类TestAction类别忘了继承下ActionSuport,写个测试方法test:
public class TestAction extends ActionSupport{
public String test(){
((HttpServletRequest)ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST))
.setAttribute("test", "Hello World!");
return "test";
}
}
然后struts.xml里配置下页面导航,这里需要注意的是result type需要写成freemarker,注意是freemarker不是freemaker,我搞不清楚为什么Struts会犯这种弱智错误,弄的我调试N久,无语中......不清楚的请参看我下面配置代码:
<action name="testAction" class="testAction">
<result type="freemarker" name="test">ftl/test.ftl</result>
</action>
test.ftl里很简单,就${test},如果没写错的话,最后访问Action的test方法浏览器会输出Hello World!
是不是觉得ftl模版写的太简单了,那就试着ftl里自定义个宏,说做就做,再建个ftl模版,内容编辑如下:
<#macro test name>
Hello ${name}!
</#macro>
<@test name="张三"/>
内容很简单,就是输出了个hello加上一个参数name值,然后本模版里调用宏,action测试类不需要更改,只需更改action导航配置,使它跳转新建的ftl模版即可。
写到这里,我还是感觉不爽,因为自定义宏就是为了模版代码重用,也就是说宏的定义和宏的调用不应该杂糅在一个模版里,实际项目中比如我们可能会分页标签写个一个宏,其他页面调用该宏即可实现分页,幸好,FreeMaker import指令支持宏的动态导入。 做法如下:
将宏定义所在模版里的宏调用语句删除,再新建个test2.ftl模版,通过import指令导入宏然后调用宏。test2.ftl内容编辑如下:
<#import "/ftl/test.ftl" as t>
<@t.test name="张三"/>
上面的t相当于命名空间的概念,个人理解哈,as t是必须的,t可以自由命名。然后t.宏名调用,后面跟着的是参数传递,so easy!
然后更改action跳转到test2.ftl即可,最后测试,看到 Hello 张三!就表明测试成功。
好,今天就到此为止吧!体会到FreeMaker的强大了没?可以 用FreeMaker来生成静态页面,可以用FreeMaker实现自定义标签,其实继承tagsuport也可以实现自定义标签,使用那种自己取舍,我建议使用FreeMaker,据说FreeMaker的解析性能很不错,而且FreeMaker实现了页面与数据及业务逻辑的独立分离,最最重要的是它强大的宏,这才是它受追捧的关键。Struts2的标签就是基于FreeMaker作为视图层组件的。
将宏定义所在模版里的宏调用语句删除,再新建个test2.ftl模版,通过import指令导入宏然后调用宏。test2.ftl内容编辑如下:
<#import "/ftl/test.ftl" as t>
<@t.test name="张三"/>
上面的t相当于命名空间的概念,个人理解哈,as t是必须的,t可以自由命名。然后t.宏名调用,后面跟着的是参数传递,so easy!
然后更改action跳转到test2.ftl即可,最后测试,看到 Hello 张三!就表明测试成功。
好,今天就到此为止吧!体会到FreeMaker的强大了没?可以 用FreeMaker来生成静态页面,可以用FreeMaker实现自定义标签,其实继承tagsuport也可以实现自定义标签,使用那种自己取舍,我建议使用FreeMaker,据说FreeMaker的解析性能很不错,而且FreeMaker实现了页面与数据及业务逻辑的独立分离,最最重要的是它强大的宏,这才是它受追捧的关键。Struts2的标签就是基于FreeMaker作为视图层组件的。
相关推荐
Freemarker学习笔记可以帮助初学者了解,快速掌握Freemarker
FreeMarker学习笔记
这篇“Freemarker学习笔记一【乱码解决】”将指导我们如何解决这个问题。 首先,我们需要了解乱码的常见原因。在Java Web开发中,乱码通常与以下因素有关: 1. **文件编码**:Freemarker模板文件(.ftl)的编码...
本压缩包集合了丰富的Freemarker学习资源,涵盖从基础到进阶的各种知识点,以下是这些文档中可能包含的详细内容: 1. **Freemarker中文手册.pdf**: 这份手册通常会详细介绍Freemarker的基本概念,如模板语言、...
1. `freemarker学习笔记.doc`:这可能是一份详细的FreeMarker学习文档,涵盖了FreeMarker的基础知识和高级特性。 2. `FullFieldTag.java`、`FullFieldCheckboxTag.java`:这两个文件可能是自定义的FreeMarker标签...
以下是对FreeMarker学习笔记的详细解释: 1. **基本语法** - **模板**:FreeMarker模板是由HTML、XML或其他文本格式组成的文件,其中包含FTL(FreeMarker Template Language)指令。模板设计者无需关注数据来源,...
`freemarker学习笔记.doc`可能包含了如何在Struts2中集成和使用Freemarker模板的详细步骤。 2. **数据绑定**:在Freemarker模板中,可以使用`<@s.action>`或`<@s.property>`等标签来直接访问Struts2 Action中的属性...
6. **学习笔记** - **入门**:从简单的变量输出开始,逐步了解FreeMarker的基本语法。 - **进阶**:掌握控制结构和逻辑,以及如何与Java对象交互。 - **实践**:通过实际项目应用,提升解决实际问题的能力。 - *...
这个“freemarker笔记”很可能是一个关于理解和使用FreeMarker模板语言的学习资料,其中可能涵盖了FreeMarker的基本概念、语法、以及在实际开发中的应用。 FreeMarker的核心概念是模板和数据模型。模板是HTML或者...
SpringBoot经典学习笔记是针对Java开发者的宝贵资源,它涵盖了SpringBoot的核心概念、特性以及实践应用。SpringBoot是由Pivotal团队开发的框架,旨在简化Spring应用的初始搭建以及开发过程,通过“约定优于配置”的...
- `Freemaker_入门+深入+开发指南+学习笔记.doc`:这份文档提供了从基础到高级的Freemarker学习路径,包括基本语法、模板设计原则和实践案例。 - `freemaeker全面教程.doc`:这份教程全面覆盖了Freemarker的各个...
### Thymeleaf 学习笔记关键知识点 #### 一、Thymeleaf 概述与优势 **Thymeleaf** 是一款现代且高级的模板引擎,它为 Web 和独立环境提供了强大的模板处理能力。根据给定内容,我们可以看出 Thymeleaf 的一些主要...
10. **jeecms学习笔记**:jeecms学习笔记.txt可能是某位开发者的学习心得,可能包含了一些实战经验和技巧。 通过这些资源,你可以系统地学习JEECMS的各个方面,从基础操作到高级开发,再到FreeMarker的运用,都能...
Spring Boot 是一个基于 Spring 框架的快速开发...这个完整的 Spring Boot 学习笔记涵盖了从基础到进阶的各个方面,通过学习和实践,你可以掌握 Spring Boot 开发的核心技能,从而高效地构建高质量的 Java 后端应用。