`
awdxzc
  • 浏览: 335096 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Freemarker 特性 和 注意事项(做项目时遇到的记录的)

阅读更多
先借鉴javaeye Robbin的文章:FreeMarker三宗罪!
http://www.iteye.com/topic/17468

引用

FreeMarker是Quake Wang推荐我使用的。刚学FreeMarker的时候,发现freemarker真的很棒!简单易用,功能强大。但是用它做了几个项目以后开始不爽了。

一宗罪:freemarker的变量必须有值,没有被赋值的变量就会抛出异常,那个黄黄的freemarker出错页面,真是让人看了太难过了。
freemarker的FAQ上面冠冕堂皇的说,未赋值的变量强制抛错可以杜绝很多潜在的错误,如缺失潜在的变量命名,或者其他变量错误。但是实际的效果是:带来的是非常大的编程麻烦,程序里面几乎所有可能出现空值的变量统统需要加上${xxx?if_exists},有些循环条件还需要写if判断,这样不但没有杜绝应该杜绝的错误,反而极大增加了编程的麻烦。

二宗罪:freemarker的map限定key必须是string,其他数据类型竟然无法操作!这一点就不讲了,JavaEye上面已经有人抱怨过了。连Webwork的开发人员Pat Lightboy都在抱怨这一点。


三宗罪:freemarker为了编程方便把不可序列化的东西往session里面放!
freemarker支持在页面里面直接操作Session,request等,例如${Session[...]},方便确实很方便,但是一旦需要做群集,就会报错。
今天是b051问起我这个问题,他在做Tomcat群集的时候发现freemarker报错,HttpSessionHashModel不可序列化。他修改该类源代码,让他实现序列化接口,仍然报错。我一看,HttpSessionHashModel包含的属性:

 private HttpSession session;  
 private final ObjectWrapper wrapper;  
   
 // These are required for lazy initializing session  
 private final FreemarkerServlet servlet;  
 private final HttpServletRequest request;  
 private final HttpServletResponse response; 


登时晕倒,这样的东西还往Session里面放?bad smell!
严重警告应用需要往群集上面发布应用的同学们,千万别用freemarker!

不过瑕不掩瑜,freemarker也是有优点的:

1、易学易用
我是看了一天文档就用得挺熟练了,freemarker文档写得太好了,例子丰富,照做一遍全都会了。

2、功能强大
比Velocity强大多了,还支持JSP Tag。不过最有意义的是macro功能,可以自定义常用的macro,实现页面常规操作的可复用性。

3、报错信息友好
很多应用服务器的JSP报错信息是无法定位到源代码行的。不过freemarker报错定位很准确,丝毫不差,而且信息丰富,一看就知道怎么回事 (虽然那个黄黄的页面看起来让人难受)



看了很多关于freemarker的评论,自己也实际项目中使用了一下,总结了一些我需要注意的地方,记录下来:
1:freemarker 对于空值的判断。 freemarker接受的对象如果是空,会直接报错。这里不管它这样设计好坏,至少我觉得我的代码里面会有很多判断空值的语句。尤其是其上一层对象出现空的时候更要判断为空的情况,单纯字符串对象你可以使用 ${obj!""}来判断obj是否为空,如果为空赋值为空字符串。使用<#if obj??>判断obj是否为空。

2:freemarker接受的map对象key只能是string类型的。

3:freemarker的自定义函数。 这个自定义函数还是很有用的,可以在freemarker接受到后台请求自定义方法后再次进入到后台进行计算。
${methodModel('${tname}','${row}')}   //methodModel 自定义的freemarker方法的类对象  在后台绑定  

componentMap.put(EnumConstants.FREEMARKER_CUSTOMIZE_METHOD_METHODMODEL.toString(), new GridMethodModel());

常量就是methodModel 这个freemarker请求的类在后台通过map绑定的key-name.
让我们看看这个类里面怎么接受这2个参数和处理这个逻辑
public class GridMethodModel implements TemplateMethodModel {

	@SuppressWarnings("unchecked")
	@Override
	public Object exec(List arg) throws TemplateModelException {
		
		Row row = null ;
		try {
			row = RowDocument.Factory.parse(arg.get(1).toString().replaceAll("xml-fragment", "per:row")).getRow();
		} catch (XmlException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String modelName = arg.get(0).toString();
		
		
		Model[] models = row.getModelArray();
		for(Model m : models)
		{
			if(modelName.equals(m.getName()))
				return m.getValue();
		}
		
		return "";
	}

}


4:freemarker几个判断类型的函数 和 简单的宏使用
引用

<#macro parse results>
<#if results?is_enumerable>
[<#list results as result><@parse results=result/><#if result_has_next>,</#if></#list>]
<#elseif results?is_hash_ex>
{<#list results?keys as key>"${key?j_string}":<@parse results=results[key]/><#if key_has_next>,</#if></#list>}
<#elseif results?is_date>"${results?string("yyyy-MM-dd")}"
<#elseif results?is_boolean>"${results?string}"
<#elseif results?is_number>"${results?c}"
<#elseif results?is_string>"${results?j_string}"
</#if>
</#macro>
<@compress single_line=true><@parse results=results/></@compress>



5:freemarker内建函数
引用

Sequence的内置函数

1.     sequence?first 返回sequence的第一个值。

2.     sequence?last  返回sequence的最后一个值。

3.     sequence?reverse 将sequence的现有顺序反转,即倒序排序

4.     sequence?size    返回sequence的大小

5.     sequence?sort    将sequence中的对象转化为字符串后顺序排序

6.     sequence?sort_by(value) 按sequence中对象的属性value进行排序

注意:Sequence不能为null。

Hash的内置函数

1. hash?keys 返回hash里的所有key,返回结果为sequence

2. hash?values 返回hash里的所有value,返回结果为sequence

操作布尔值


string 用于将布尔值转换为字符串输出

true转为“true”,false转换为“false”

foo?string(“yes”,”no”)如果布尔值是true,那么返回“yes”,否则返回no

操作数字

1.c 用于将数字转换为字符串

${123?c} à结果为123

2.string用于将数字转换为字符串

Freemarker中预订义了三种数字格式:number,currency(货币)和percent(百分比)其中number为默认的数字格式转换

例如:

<#assign tempNum=20>

${tempNum}   

${tempNum?string.number}或${tempNum?string(“number”)} à结果为20

${tempNum?string.currency}或${tempNum?string(“currency”)} à结果为¥20.00

${tempNum?string. percent}或${tempNum?string(“percent”)} à结果为2,000%


freemarker 的内建函数 contains 的使用:

<#if employee.departments?contains(department)>checked="checked"</#if>

其中departments是一个集合,而department是departments集合里的一个元素。contains函数可以判断出,元素 department是否存在于集合departments里,最终返回一个Boolean


Sequence内置的分段器: chunk
用途:某些比较BT的排版需求
模板:

<#assign seq = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']> 
<#list seq?chunk(4) as row> 
<ul> 
<li><#list row as cell>${cell} </#list></li> 
</ul> 
</#list> 

<#list seq?chunk(4, '-') as row> 
<tr> 
<td><#list row as cell>${cell} </#list></td> 
</tr> 
</#list> 



输出:
引用

<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
<ul>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
</ul>
<ul>
<li>i</li>
<li>j</li>
</ul>

<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr>
<td>e</td>
<td>f</td>
<td>g</td>
<td>h</td>
</tr>
<tr>
<td>i</td>
<td>j</td>
<td>-</td>
<td>-</td>
</tr>




    以后有时间继续补充freemarker宏定义和使用以及freemarker调用java静态方法的好处和使用方法。


分享到:
评论

相关推荐

    freemarker 简单项目示例

    - 数据模型是Freemarker模板渲染时的数据来源,可以是Java对象、Map或POJO。 - 在这个示例中,可能有一个名为`testModel`的数据模型,包含用于渲染模板的属性。 5. **模板处理** - 使用Freemarker API创建`...

    velocity和freemarker的比较

    以上是对Velocity和FreeMarker的基本介绍和比较,它们都是Java Web开发中的重要工具,理解它们的特性和应用场景有助于选择最适合项目的技术栈。对于标签“源码”和“工具”,我们可以进一步研究这两个模板引擎的源...

    Velocity 和 FreeMarker区别

    - **FreeMarker**拥有一个庞大的用户群和活跃的社区支持,这意味着在遇到问题时更容易找到解决方案。 - **Velocity**虽然社区规模较小,但也有一批忠实的用户和支持者。 #### 六、应用场景 - **Velocity**更适合于...

    模板:velocity和freemarker的比较

    Velocity和Freemarker模板技术比较 模板技术在现代软件开发中...在选择模板技术时,我们需要考虑到项目的需求和性能要求,然后根据实际情况选择合适的模板技术。模板技术可以提高我们的开发效率,提高我们生产的质量。

    freemarker 自定义freeMarker标签

    FreeMarker 是一个强大的模板引擎,常用于Java应用中生成HTML、XML等动态内容。它允许开发者使用简单的模板语言...通过深入理解FreeMarker的工作原理和API,开发者可以构建出更强大、更符合项目需求的模板解决方案。

    原创 用FreeMarker宏 和 Jquery 做树(Hbiernate和JDBC版)

    标题 "原创 用FreeMarker宏 和 Jquery 做树(Hbiernate和JDBC版)" 描述了如何使用FreeMarker模板引擎的宏功能,结合jQuery库,创建一个可展示层次结构数据的树形视图。在这个过程中,可能涉及了两个主要的技术:...

    SSH项目 有Freemarker模版

    在这个项目中,"SSH项目 有Freemarker模版" 意味着它采用了Struts2作为MVC框架,Spring作为依赖注入容器和服务层管理,Hibernate作为对象关系映射工具,同时利用了Freemarker作为模板引擎来渲染前端视图。...

    struts2+hibernate+freemarker项目实例

    在学习和使用这个项目实例时,你需要理解每个框架的核心概念和工作原理,如Struts2的动作(Action)和结果(Result),Hibernate的实体(Entity)、会话(Session)和查询,以及FreeMarker的模板语法。此外,还需要...

    eclipse的freemarker插件

    Eclipse是一款广泛使用的Java集成开发环境(IDE),它支持多种编程语言和开发工具。而Freemarker则是一种轻量级的、基于...如果你在Eclipse中处理Freemarker项目,安装这样一个插件会极大地提高你的开发体验和生产力。

    jsp、freemarker、velocity简介和对比

    - **模板嵌入能力**:Freemarker支持运行时动态嵌入模板,而JSP和Velocity在这方面的能力较弱。 - **语法与可读性**:Freemarker的语法更加简洁,易于阅读和维护;而JSP则由于混合了HTML与Java代码,可能会导致...

    Spring+Maven+freemarker+Ibatis项目

    在当今的软件开发领域,Spring、Maven、Freemarker和Ibatis是四个非常重要的开源框架和技术,它们共同构建了一个高效、灵活且可维护的Java Web项目。这篇详述将深入探讨这四大组件的集成与应用。 一、Spring框架 ...

    freemarker各种版本的jar包

    使用这些不同版本的Freemarker jar包时,开发者可以根据项目的具体需求来选择合适的版本。例如,如果项目对性能有较高要求,可能会倾向于选择较新版本,因为它们通常包含性能优化。同时,也要注意与现有项目依赖库的...

    springboot+webflux+mongodb+freemarker

    【标题】"SpringBoot+WebFlux+MongoDB+FreeMarker"是一个综合性的技术栈,主要涉及四个核心组件,它们分别是Spring Boot、WebFlux、MongoDB和FreeMarker。这四个组件共同构建了一个轻量级、反应式和非阻塞式的Web...

    struts2和freemarker整合

    FreeMarker 2.3.16是FreeMarker模板语言的一个版本,提供了详细的文档,涵盖了FreeMarker的所有特性和用法。该手册通常会包含以下内容: 1. **基础概念**:解释了FreeMarker模板语言的基本元素,如变量、控制结构...

    freemarker-2.3.23jar

    8. **错误处理**:当模板存在错误时,Freemarker会抛出异常,并提供详细的错误信息,帮助开发者快速定位问题。 9. **API和配置**:Java应用程序可以使用Freemarker提供的API来加载、解析和渲染模板。同时,...

    Struts2 和freemarker实例

    Struts2提供了丰富的特性,如拦截器、插件架构、灵活的数据绑定以及强大的表单验证功能,使得开发者能够更高效地组织和管理应用程序的业务逻辑。 FreeMarker则是一个模板引擎,它允许开发者使用模板语言来分离应用...

    springboot集成freemarker和shiro框架

    而FreeMarker和Shiro则分别是常用的模板引擎和安全框架,它们能帮助我们构建出功能强大且安全的Web应用。本文将详细讲解如何在SpringBoot项目中整合这两者。 **一、FreeMarker简介** FreeMarker是一个基于模板的...

    freemarker Demo 适用于freemarker初学

    这个"freemarker Demo"是一个适合初学者的示例项目,旨在帮助新接触Freemarker的开发者快速理解和上手。 1. **Freemarker简介** Freemarker是一个基于模板的开源模板语言,它与Java代码分离,使得开发者可以专注于...

    freemarker的分页功能

    标题与描述概述的知识点主要集中在Freemarker模板引擎在实现分页功能时的应用,特别是当后端数据库为MySQL的情况下。Freemarker是一个用于生成动态文本的模板引擎,它被广泛应用于Web开发中,用于将数据模型转换成...

    FreeMarker概述

    FreeMarker概述、FreeMarker特性、FreeMarker应用指南

Global site tag (gtag.js) - Google Analytics