`
Fly_m
  • 浏览: 259644 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

freemarker从试用到放弃

阅读更多

    前两天,周末在家无事,想起以前的项目是基于struts2开发的,而在struts2中又大量运用了freemarker,所以就想也去试用下freemarker。

    在struts2的guide文章中,说明了为什么要使用freemarker的理由。

The framework utilizes FreeMarker because the engine includes strong error reporting, 
built-in internationalization and powerful macro libraries.

    即准确的错误地方以及内置的国际化处理以及强大的自定义宏处理。

 

    从网上下载了一个简单的freemarker中文文档以及官方的手册,简单看了下,然后开始处理中。首先根据每个界面都需要引用相同的html代码以及结尾处理。写了一个简单的html.ftl信息,然后在每个界面都包含进来。如下

<#assign g=JspTaglibs["/WEB-INF/gtip.tld"] />
<#macro body title="标题">
<!DOCTYPE html>
<html>
<head>
	<title>${title}</title>
	<#include "header.ftl" />
</head>
<body>
	<#nested />
</body>
</html>
</#macro>

 

就是简单的一个宏处理,以及声明包含一个自定义的jsptag信息,将title信息写进head中的title标签,然后引用公共使用的header.ftl(即相应的js以及css),最后在body标签中调用相应的代码信息。

 

    这样在其他界面中,只需要<#include "html.ftl"/>,然后再调用<@body>这个宏即可。

    接下来,就是将每个界面的jsp修改为ftl了,除了在struts.xml中修改每个result的type为freemarker之外,还需要将每个jsp重新copy成ftl,然后进行改造。

    对于每个ftl,首先将原来的<s:调用方式,修改为freemarker的<@s.的调用方式。如<s:iterator>修改为<@s.iterator>这样的形式。我使用了一个正则表达式来进行字符替换,使用 (?<=<(?:/)?)(\w): 来匹配相应的标签,并使用 @\$1. 来替换掉。上面的字符会匹配<s:iterator中的<s:,也可以匹配</s:iterator中的</s:,直接将其替换即可。

    其次,将其中的<s:property value="XX"/>的形式(经第一步之后,变成了<@s.property value="XX"/>了),修改为${xxx}的形式。因为使用freemarker嘛,所以要修改过来。这里也使用了一个正则表达式进行替换,由 <@s.property value="#?([\w\.]+)"/> 替换为 \\$\{\$1} ,即可实现这个修改。

 

    接下来修改其他标签。

    将<@s.iteraotr标签,修改为<#list >的形式;

    将<@s.if></@s.if><@s.else>修改为<#if><#else>的形式。

   

    花了近一天的时候,终于将相应的界面修改了。最后重新启动工程进行运行,结果出问题了。问题有以下几个:

1,如果ftl界面不能完全解析,则相应的界面将完全以源代码的形式显示在界面上。

    这个问题,由于比如其中的某些type没有正则的匹配相应的ftl,而后台以dispatcher的形式返回回来之后,界面就直接将整个ftl文件完整地显示在界面上了。这样对于文件的保护,而且对于开发来说都是不大好的。

2,首页以及登陆界面的问题。

    如果将首页以及相应的前台界面修改为ftl的形式,那么在进行访问的时候就必须以非ftl的形式进行访问了,如通过xxx.do的形式进行访问,这样还必须给相应的ftl文件追加相应的action匹配。如原来的login.jsp,现在就必须以login.do进行访问,而且需要给这个映射追加一个action映射信息。如果前面界面有很多,面分散在不同的目录中,那么就需要有多个不同的匹配来进行, 这样无凝增加了无谓的工作。

    当然有一个解决办法就是保存前台界面为jsp不变,但又出现新的问题,即当前台界面引用其他界面时,又会出现相同的问题。即其他界面均修改为ftl,而ftl中有相应的freemarker解析标签。如login.jsp引用error.ftl时,将会出现error.ftl中的信息不能被解析的问题。当然可以保存error.ftl和error.jsp同时存在。但这样就失去了freemarker的作用了。

3,最重要的,toString问题和null问题以及map问题

    3.1 freemarker没有对list以及map结构有一个很好的toString支持,即直接调用${x}时,如果x为一个list时,将直接显示一个List@xxx的形式。这样,就要求我们必须为其编写一个sequenceToString的macro,而且还需要在调用中对x的类型进行判断(通过?_isXXX的形式),再进行相应的处理。

    3.2 map问题,即freemarker中不能支持非string的key值,这样在进行一些复杂迭代时就需要作一些其他的转换,如将一个map拆分为两个或多个map。

    3.3 三元运算符的支持。由于缺少三元运行符,所以在一些复杂的判断中,为一个变量进行赋值时,就需要用多个<#if和<#else>进行处理。本来只需要一个三元运算就能解决的问题,由用<#if和<#else>就需要写很长一段代码。

    3.4 null问题。这是最重要的,freemarker没有一个默认的null处理,甚至也不接受一个null值。如x=null(X变量是存在的),打印${x}时,将直接报一个错误,而不是打印类似的""值或null等。这样在进行很多显示中,都需要在相应的变量后面加一个!,如${x!}这样的形式,很是麻烦。

    在<#list中,也需要使用类似<#if (list)!>的形式。而由于缺少对null的支持,需要写一个类似x==null这样的判断时,就需要写成!(x??)的特殊形式,而且到处均需要写成(XX?method?method)?或!的形式以进行null的处理。

 

    导致我决定不使用freemarker的原因,就是现阶段没有发现其比struts2标签更方便。尤其在对于null的处理上,ognl标签相比来说更容易使用,当碰到出现类似nullPointer的时候,struts2标签在处理时将直接采用默认的处理方式,如显示为""(对于iterator或if时,将直接返回false,以结束迭代或判断)。这样就不需要开发人员再去进行无谓的null处理,而这个结果正是在web开发中所需要的。

 

    网上再找了下,freemarker对于一些模板文件的生成还是很有用的,比如在项目中,就依照struts2的标签开发用freemarker生成一个tree树,再采用标签进行封装来调用。如下所示:

<#-- 写一个子集列表 -->
<#macro writeOne node expand>
<li>
	<input type="checkbox" name="${node.nameParam}" value="${node.id}"
			<#if node.checked>
		   checked="checked"
			</#if>
			/>
	<span>${node.name}</span>
	<#if expand && (node.childList?? && node.childList?size > 0)>
	<ul>
		<@write nodeList=node.childList expand=expand/>
	</ul>
	</#if>
</li>
</#macro>

<#-- 写上级结点 -->
<#macro write nodeList expand>
<#list nodeList as node>
<@writeOne node=node expand=expand/>
</#list>
</#macro>
		<@write nodeList=parameters.nodeList expand=parameters.expand/>

 

   最后决定,在进行jsp开发上,还是使用jsp+struts2标签进行开发,而使用一些模板文件生成的时候,或许可以考虑一下freemarker。至少对于我来说,freemarker已经没有那么大的吸引力了。

分享到:
评论
9 楼 spiniper 2014-12-14  
cnboss 写道

如果是为了代替jsp所实现的功能,我认为freemarker除了性能上的优势外没有任何优势可言!

更好的实现mvc?前端用jsp就不是mvc?

谁告诉你jsp中必须要出现java代码的,一个代码规约就可完全限定jsp中不允许出现java代码。如果拿jsp中出现java代码而freemarker没有也算作是freemarker优点的话,我只能呵呵了,先去了解一下el表达式,jstl吧,这两者不比freemarker更优雅?null简直就是浮云。

不要盲目相信freemarker的优势,多去接触和比较再来说

我可以告诉你,我用jsp用了5年,用freemarker用了3年,虽然我不敢说我多精通jsp,也不敢说我多精通freemarker,但是我了解jsp的方方面面,也同样了解freemarker的方方面面,我不知道你说的多接触是怎样一种多接触?我想8年的时间去体会两个东西的好坏应该足够了,你说呢?如果不排除标准的问题,freemarker其实完胜jsp,无论从代码集成度,实现灵活性,运行效率,语法优雅性(虽然这是个个人感官问题),都超越jsp,唯一不如jsp的,估计就是蛋疼的IDE支持,我只想反问你一句,你有真正了解freemarker么?我可以很负责任的告诉你,我是真的接触他们很长时间才敢说这话的,我也不怕告诉你,我web就是开发jsp出道的,我也曾经鄙视过freemarker,因为那时的目光短浅、学识浅薄和包容心差。
8 楼 foible 2014-11-11  
cnboss 写道
spiniper 写道
不要因为自己的无能而去评价一个框架的好坏,很多时候事实证明并不是那个框架有问题,而是自己有问题,freemarker作为一个发展了这么多年的页面模板,虽然不能说十全十美,但是也不是那么的不中用。很多程序员都有与博主一样的毛病,就是有了一个先入为主的模式以后,就会以这个模式去思考另外一个框架的模式,由于那个框架与自己的思维模式格格不入就说那个框架不好,最典型的就是很多人用了struts1就都说webwork不好,直到struts2用了webwork。
struts2标签确实很强大,有着一套自己的解析体系,用起来也很方便,在很多方面也很省事,但是struts2标签有个巨大的短板就是性能,它要为其强大的解析能力去消支付多的资源。相对于freemarker在这方面则更优秀。
相对于jsp而言,freemarker的优势就更加明显了,且不说功能上,jsp能实现的freemarker都能实现,且代码更加优雅且规范,不像jsp还得限制开发人员不能使用java元素编写jsp。而且jsp的标签体系也比较繁琐复杂,不像freemarker那样简单直接。且jsp标签的属性注入存在线程问题,需要做一些特殊处理才能正确工作。
对于null的问题,这本身根本就是个见仁见智的问题,并不能说明freemarker的不好,只是freemarker认为null问题必须显示处理来引导一个强规范,而不像jsp 的null处理为""空字符串,因为""空字符串并不是null,jsp混淆了这个问题,很多时候在一些严谨的业务中,这种问题也许是灾难性的。


如果是为了代替jsp所实现的功能,我认为freemarker除了性能上的优势外没有任何优势可言!

更好的实现mvc?前端用jsp就不是mvc?

谁告诉你jsp中必须要出现java代码的,一个代码规约就可完全限定jsp中不允许出现java代码。如果拿jsp中出现java代码而freemarker没有也算作是freemarker优点的话,我只能呵呵了,先去了解一下el表达式,jstl吧,这两者不比freemarker更优雅?null简直就是浮云。

不要盲目相信freemarker的优势,多去接触和比较再来说






看到你的第一句话,我笑cry了,所有语言或者框架都是把性能排第一位的,再简单再易用性能不好都白搭。

我再多一句,freemarker是模版语言,替代jsp只是它的一部分功能,更多的是解决重复性的问题而产生的。举个例子:知道自动的代码生成器吗?
7 楼 cnboss 2014-10-24  
spiniper 写道
不要因为自己的无能而去评价一个框架的好坏,很多时候事实证明并不是那个框架有问题,而是自己有问题,freemarker作为一个发展了这么多年的页面模板,虽然不能说十全十美,但是也不是那么的不中用。很多程序员都有与博主一样的毛病,就是有了一个先入为主的模式以后,就会以这个模式去思考另外一个框架的模式,由于那个框架与自己的思维模式格格不入就说那个框架不好,最典型的就是很多人用了struts1就都说webwork不好,直到struts2用了webwork。
struts2标签确实很强大,有着一套自己的解析体系,用起来也很方便,在很多方面也很省事,但是struts2标签有个巨大的短板就是性能,它要为其强大的解析能力去消支付多的资源。相对于freemarker在这方面则更优秀。
相对于jsp而言,freemarker的优势就更加明显了,且不说功能上,jsp能实现的freemarker都能实现,且代码更加优雅且规范,不像jsp还得限制开发人员不能使用java元素编写jsp。而且jsp的标签体系也比较繁琐复杂,不像freemarker那样简单直接。且jsp标签的属性注入存在线程问题,需要做一些特殊处理才能正确工作。
对于null的问题,这本身根本就是个见仁见智的问题,并不能说明freemarker的不好,只是freemarker认为null问题必须显示处理来引导一个强规范,而不像jsp 的null处理为""空字符串,因为""空字符串并不是null,jsp混淆了这个问题,很多时候在一些严谨的业务中,这种问题也许是灾难性的。


如果是为了代替jsp所实现的功能,我认为freemarker除了性能上的优势外没有任何优势可言!

更好的实现mvc?前端用jsp就不是mvc?

谁告诉你jsp中必须要出现java代码的,一个代码规约就可完全限定jsp中不允许出现java代码。如果拿jsp中出现java代码而freemarker没有也算作是freemarker优点的话,我只能呵呵了,先去了解一下el表达式,jstl吧,这两者不比freemarker更优雅?null简直就是浮云。

不要盲目相信freemarker的优势,多去接触和比较再来说




6 楼 springdata 2014-08-01  
5 楼 winie 2013-12-04  
你说得对!技术无法是解决需求,当然有得有失,适合自己的就可以!
4 楼 spiniper 2013-11-20  
foible 写道

我赞同你的部分观点,但你得告诉我freemarker有三元运算符不?

纠结...
好吧,freemarker没那玩意。
不过我想问,有没有那个玩意很重要么?
或许你想说没三元运算符很多地方会不够方便,简洁,甚至是你觉得不够优雅?
但是我觉得,作为一个模板语言,三元运算符就是个鸡肋,没用,你不能把freemarker去和C++或者java这种语言相提并论吧,他只是个模板语言而已,更何况freemarker支持java模板的构建和java函数的构建,为什么你一定要去纠结在freemarker中使用三元运算符,java中用不好么?
3 楼 foible 2013-09-25  
spiniper 写道
不要因为自己的无能而去评价一个框架的好坏,很多时候事实证明并不是那个框架有问题,而是自己有问题,freemarker作为一个发展了这么多年的页面模板,虽然不能说十全十美,但是也不是那么的不中用。很多程序员都有与博主一样的毛病,就是有了一个先入为主的模式以后,就会以这个模式去思考另外一个框架的模式,由于那个框架与自己的思维模式格格不入就说那个框架不好,最典型的就是很多人用了struts1就都说webwork不好,直到struts2用了webwork。
struts2标签确实很强大,有着一套自己的解析体系,用起来也很方便,在很多方面也很省事,但是struts2标签有个巨大的短板就是性能,它要为其强大的解析能力去消支付多的资源。相对于freemarker在这方面则更优秀。
相对于jsp而言,freemarker的优势就更加明显了,且不说功能上,jsp能实现的freemarker都能实现,且代码更加优雅且规范,不像jsp还得限制开发人员不能使用java元素编写jsp。而且jsp的标签体系也比较繁琐复杂,不像freemarker那样简单直接。且jsp标签的属性注入存在线程问题,需要做一些特殊处理才能正确工作。
对于null的问题,这本身根本就是个见仁见智的问题,并不能说明freemarker的不好,只是freemarker认为null问题必须显示处理来引导一个强规范,而不像jsp 的null处理为""空字符串,因为""空字符串并不是null,jsp混淆了这个问题,很多时候在一些严谨的业务中,这种问题也许是灾难性的。



我赞同你的部分观点,但你得告诉我freemarker有三元运算符不?
2 楼 winie 2013-06-09  
你可以试试httl 国产的 当然没有freemarker成熟!但是感觉很不错!
1 楼 spiniper 2012-11-09  
不要因为自己的无能而去评价一个框架的好坏,很多时候事实证明并不是那个框架有问题,而是自己有问题,freemarker作为一个发展了这么多年的页面模板,虽然不能说十全十美,但是也不是那么的不中用。很多程序员都有与博主一样的毛病,就是有了一个先入为主的模式以后,就会以这个模式去思考另外一个框架的模式,由于那个框架与自己的思维模式格格不入就说那个框架不好,最典型的就是很多人用了struts1就都说webwork不好,直到struts2用了webwork。
struts2标签确实很强大,有着一套自己的解析体系,用起来也很方便,在很多方面也很省事,但是struts2标签有个巨大的短板就是性能,它要为其强大的解析能力去消支付多的资源。相对于freemarker在这方面则更优秀。
相对于jsp而言,freemarker的优势就更加明显了,且不说功能上,jsp能实现的freemarker都能实现,且代码更加优雅且规范,不像jsp还得限制开发人员不能使用java元素编写jsp。而且jsp的标签体系也比较繁琐复杂,不像freemarker那样简单直接。且jsp标签的属性注入存在线程问题,需要做一些特殊处理才能正确工作。
对于null的问题,这本身根本就是个见仁见智的问题,并不能说明freemarker的不好,只是freemarker认为null问题必须显示处理来引导一个强规范,而不像jsp 的null处理为""空字符串,因为""空字符串并不是null,jsp混淆了这个问题,很多时候在一些严谨的业务中,这种问题也许是灾难性的。

相关推荐

    freemarker 自定义freeMarker标签

    本篇将深入探讨如何自定义FreeMarker标签,以扩展其功能并适应特定项目需求。 首先,理解FreeMarker的默认标签语法至关重要。FreeMarker使用${...}表达式来插入变量,#{...}用于输出注释,以及、等控制结构进行条件...

    freemarker Demo 适用于freemarker初学

    在Java应用中,Freemarker通过ModelAndView或者Map对象将数据传递到视图层。开发者可以在Java后端准备数据模型,然后传递给Freemarker模板,模板根据模型中的数据生成HTML输出。 4. **与Struts2集成** Struts2是...

    freemarker

    在提供的代码片段中,`FreemarkerUtil`类封装了Freemarker的基本操作,包括模板的获取、数据模型的处理以及输出到流或文件。其中`getTemplate`方法负责模板的加载,而`print`和`fprint`方法分别用于输出到控制台和...

    freemarker.jar

    camel-freemarker-1.6.4.jar, camel-freemarker-2.8.1.jar, com.springsource.freemarker-2.3.15.jar, com.springsource.freemarker-sources-2.3.15.jar, freemarker-1.4.1.jar, freemarker-2-3-18.jar, freemarker-...

    freemarker-2.3.23jar

    `freemarker-2.3.23.jar`是Freemarker库的一个版本,发布于2.3.23,这个版本可能包含了对早期版本的一些改进、新功能或bug修复。 Freemarker的核心概念是模板语言,它是一种声明式的编程方式,允许开发者编写不包含...

    eclipse的freemarker插件

    版本号"0.9.14"表示这是该插件的一个具体版本,用户可以根据实际需求选择安装相应版本,或者升级到最新版本以获取更多改进和新功能。 总的来说,"eclipse的freemarker插件"是Eclipse开发环境中不可或缺的工具之一,...

    freemarker项目(从入门到与struts2结合)

    1. **安装与配置**:FreeMarker是一个轻量级库,可以通过Maven或Gradle等构建工具引入到Java项目中。配置主要涉及设置模板目录和配置文件`freemarker.properties`,其中定义了FreeMarker的行为,例如模板的缓存策略...

    freemarker-2.3.28.jar

    在实际应用中,开发者通常会将这个JAR文件添加到项目的类路径(classpath)中,以便在运行时能够解析和执行Freemarker模板。如果在Eclipse中使用,可以将该JAR文件添加到项目的构建路径,确保项目能正确识别并利用...

    FreeMarker手册-Freemarker 2.3.18

    FreeMarker 2.3.18是该引擎的一个版本,它提供了一系列的更新和改进,以提高性能和易用性。 1. **模板语言基础** FreeMarker的模板语言是一种声明式的编程方式,它允许开发者通过简单的标记语法来控制输出。这些...

    freemarker 源码、中文API、 freemarker Myeclipse 编辑器

    总的来说,这个压缩包提供了一套完整的Freemarker学习资源,从基本的API文档到开发环境的集成工具,再到源码级别的深入研究。无论是初学者还是有经验的开发者,都可以从中找到自己需要的信息,提升对Freemarker的...

    freemarker-2.3.30-API文档-中文版.zip

    赠送jar包:freemarker-2.3.30.jar; 赠送原API文档:freemarker-2.3.30-javadoc.jar; 赠送源代码:freemarker-2.3.30-sources.jar; 赠送Maven依赖信息文件:freemarker-2.3.30.pom; 包含翻译后的API文档:...

    freemarker-2.3.31-API文档-中文版.zip

    赠送jar包:freemarker-2.3.31.jar; 赠送原API文档:freemarker-2.3.31-javadoc.jar; 赠送源代码:freemarker-2.3.31-sources.jar; 赠送Maven依赖信息文件:freemarker-2.3.31.pom; 包含翻译后的API文档:...

    FreeMarker

    1. **变量与表达式**:在FreeMarker模板中, `${variable}` 用于表示变量,它会从数据模型中查找对应的值并输出。表达式支持算术运算、比较运算和逻辑运算,例如 `${a + b}`、`${c &gt; d}` 和 `${e && f}`。 2. **...

    FreeMarker2.3.23官方中文文档

    2.3.23是FreeMarker的一个稳定版本,这个版本的官方中文文档提供了全面的指导和说明,帮助开发者更好地理解和使用这个模板语言。 在FreeMarker的核心概念中,它是一个基于数据驱动的模板语言。这意味着,开发者不...

    freemarkerdemo 生成word 插入图片

    在这个"freemarkerdemo生成word插入图片"的示例中,我们主要探讨如何利用Freemarker来创建Word文档,并且将图片集成到这些文档中。这个过程涉及到几个关键的技术点: 1. **Freemarker基础知识**:Freemarker是一个...

    freemarker编辑插件

    "freemarker编辑插件"能够集成到Eclipse中,使得开发者在编写Freemarker模板时可以享受到诸如语法高亮、自动完成、错误检查等功能。这个插件的版本为0.9.14,可能包含了对Freemarker语法的最新支持以及一些优化的...

    freemarker替换变量实例

    freemarker替换变量实例

    模板:velocity和freemarker的比较

    再者,从语法格式上来讲,Velocity 和 Freemarker 的语法格式不同,Velocity 的语法更加简洁,而 Freemarker 的语法更加灵活。不同的开发者可能会有不同的倾向性,但是Freemarker 的语法更加强大。 最后,从性能上...

    FreeMarker通用的分页

    如果当前页小于等于一半显示页数,则显示从第一页开始的页码;反之,显示以当前页为中心的页码。 - **分段显示页码**:根据当前页和总页数,分两段显示页码。首先显示前半部分,然后是后半部分。这确保了用户界面的...

Global site tag (gtag.js) - Google Analytics