`
Fly_m
  • 浏览: 259680 次
  • 性别: 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已经没有那么大的吸引力了。

分享到:
评论
29 楼 u013683677 2017-06-13  
看了你的一些问题描述,我发现你可能没真正了解freemarker的用法。。。
28 楼 ylmotol7 2016-05-11  
javamonkey 写道
zyyy358 写道
在所有的java模板引擎,php模板引擎中,目前我还没找到比freemarker更优秀的

如果非要用freemarker去替代jsp确实很痛苦,但是如果你有机会了解和使用freemarker的所有特性,你就会抛弃这种先入为主的想法了。

我在自己搭建的项目中,使用了SpringMVC,和freemarker。只是使用了SpringMVC直接处理了所有get请求,直接将文件地址透明的交给了freemarker做视图处理。 惊喜的发现,直接将美工做好的html放到我的框架模板目录下就可以访问了,然后只需要将样例数据替换成动态数据,大部分展示功能就完成了。然后在单独的Controller去处理一些特殊逻辑和表单接受就可以直接交差啦。

freemarker的自定义标签功能 是直接影响我开发模式的一种特性,利用这种特性,我直接将视图层做成通用分发规则,当需要哪些后台数据时,再使用自定义标签去 控制层回调数据过来。即做到了 MVC分层,也实现了数据调取的灵活性。


用beetl ibeetl.com,好很多


都用过,beetl一般般
27 楼 ylmotol7 2016-05-11  
一炮送你回车库 写道
再说一句,现在web开发是ajax的天下,freemarker还有多大的价值呢?

ajax并不是万能的,恰巧有的东西ajax就是搞不定
26 楼 ylmotol7 2016-05-11  
我也笑了。。。
25 楼 wangyi878750 2016-03-30  
笑了
24 楼 aqi0796 2016-02-14  
jsp和模板类的有阵没用了,目前用的基本都是后端SOA多点横扩+前端的RESTful的HTTP API,页面一般是angular js这类的由H5开发人员专门做。
23 楼 spiniper 2015-12-17  
一炮送你回车库 写道
现在还有很多人在乎jsp的直接嵌入java代码吗?只要不是逻辑性强的java代码,跟freemarker和jsp的标签其实是一个意思,完全没必要用所谓的这种标签框架。最烦有些人说的语法优雅性,人工制造开发难度,最易开发和维护、学习成本低、性能良好的代码就是最好的代码。现在是2015年了不是2008年了,让freemarker去坟墓吧。

freemarker和jsp我都很精通,如果让我选型我会选freemarker,但是用jsp我也觉得很好,但是你说的在jsp上写java代码,我只想说你这是校园思维,jsp不是不建议写java代码,而是不能写java代码,不是因为代码优雅的问题,而是因为web容器兼容的问题,因为很多时候你开发是一个环节,而正是服务器是另一个环境,因此jsp从开发到部署环境存在容器兼容差异,如果你jsp使用java代码,你会碰到很多你想破头也找不到的jsp解析错误,在你自己开发环境随便跑,上了服务器就出错的坑。
22 楼 spiniper 2015-12-17  
一炮送你回车库 写道
再说一句,现在web开发是ajax的天下,freemarker还有多大的价值呢?

我不评价你个人开发的喜好,不过你的言论让我感觉似乎有人在说:有很多东西是科学解释不了的,那种话的感觉。
21 楼 xiaoxiongsoft 2015-12-11  
2015年12月,用html5+angular+控制层(springmvc/rpc)框架
20 楼 lingcen000 2015-09-06  
这个我用的很少,第一印象很不好,就是因为null问题,如果某个对象的某个String属性是null,必须<#if ( A.xx?? )> 这样单独判断,而不能<#if (A.xx?? && A.xx == "dd" )>这样写,否则就报A.xx未定义,但是如果xx是基本类型的对象类型的话<#if (A.xx?? && A.xx=="dd" )> 这样写又没问题了。
18 楼 一炮送你回车库 2015-07-21  
再说一句,现在web开发是ajax的天下,freemarker还有多大的价值呢?
17 楼 一炮送你回车库 2015-07-21  
现在还有很多人在乎jsp的直接嵌入java代码吗?只要不是逻辑性强的java代码,跟freemarker和jsp的标签其实是一个意思,完全没必要用所谓的这种标签框架。最烦有些人说的语法优雅性,人工制造开发难度,最易开发和维护、学习成本低、性能良好的代码就是最好的代码。现在是2015年了不是2008年了,让freemarker去坟墓吧。
16 楼 hhzgq 2015-06-05  
hhzgq 写道
无论什么技术,能对用户友好,能对搞开发的友好,就是最好的。至于,用什么不用什么,基本不是某个人说了算的。一个项目几十个人开发,不可能因为你一个人觉得Java不好用,就几十个人一起改用php。(当然了,例子可能有点不恰当。)什么技术好,什么技术不好,仁者见仁智者见智。如果你实在是觉得这门技术不好学,现在又不着急用,你大可一边工作一边学习。等到公司真的用到这门技术的时候,也不至于心里起急。一个好的程序员,绝对不会对技术挑肥拣瘦。如果你真的十分熟悉FreeMark,觉得这个框架有很多缺点。不如直接给官方的项目组去个Email反映下情况。或者,干脆自己写个框架把这个框架的缺点弥补一下。

对不起,手误了。FreeMark应改为FreeMarker!
15 楼 hhzgq 2015-06-05  
无论什么技术,能对用户友好,能对搞开发的友好,就是最好的。至于,用什么不用什么,基本不是某个人说了算的。一个项目几十个人开发,不可能因为你一个人觉得Java不好用,就几十个人一起改用php。(当然了,例子可能有点不恰当。)什么技术好,什么技术不好,仁者见仁智者见智。如果你实在是觉得这门技术不好学,现在又不着急用,你大可一边工作一边学习。等到公司真的用到这门技术的时候,也不至于心里起急。一个好的程序员,绝对不会对技术挑肥拣瘦。如果你真的十分熟悉FreeMark,觉得这个框架有很多缺点。不如直接给官方的项目组去个Email反映下情况。或者,干脆自己写个框架把这个框架的缺点弥补一下。
14 楼 ylmotol7 2015-05-25  
无意当中看到这个文章
说实话,你抱怨的oString问题和null问题以及map问题完全不是问题!
jsp做静态化好做?
jsp判断好写?
jsp格式化好写?
jsp太麻烦了。。。当你有一天重构页面的时候你就知道多蛋疼了!
抱怨之前,还是多学习学习吧,就因为一个周末的时间就能学好?
13 楼 netwelfare 2015-05-19  
楼主的想法太偏激了,如果你深入的研究一下freemarker的实现,你会发现其实freemarker还是挺伟大的,推荐你看看这些内容,从底层讲解了freemarker的实现,很不错的:freemarker系列
12 楼 javamonkey 2015-04-16  
zyyy358 写道
在所有的java模板引擎,php模板引擎中,目前我还没找到比freemarker更优秀的

如果非要用freemarker去替代jsp确实很痛苦,但是如果你有机会了解和使用freemarker的所有特性,你就会抛弃这种先入为主的想法了。

我在自己搭建的项目中,使用了SpringMVC,和freemarker。只是使用了SpringMVC直接处理了所有get请求,直接将文件地址透明的交给了freemarker做视图处理。 惊喜的发现,直接将美工做好的html放到我的框架模板目录下就可以访问了,然后只需要将样例数据替换成动态数据,大部分展示功能就完成了。然后在单独的Controller去处理一些特殊逻辑和表单接受就可以直接交差啦。

freemarker的自定义标签功能 是直接影响我开发模式的一种特性,利用这种特性,我直接将视图层做成通用分发规则,当需要哪些后台数据时,再使用自定义标签去 控制层回调数据过来。即做到了 MVC分层,也实现了数据调取的灵活性。


用beetl ibeetl.com,好很多
11 楼 zyyy358 2015-01-01  
在所有的java模板引擎,php模板引擎中,目前我还没找到比freemarker更优秀的

如果非要用freemarker去替代jsp确实很痛苦,但是如果你有机会了解和使用freemarker的所有特性,你就会抛弃这种先入为主的想法了。

我在自己搭建的项目中,使用了SpringMVC,和freemarker。只是使用了SpringMVC直接处理了所有get请求,直接将文件地址透明的交给了freemarker做视图处理。 惊喜的发现,直接将美工做好的html放到我的框架模板目录下就可以访问了,然后只需要将样例数据替换成动态数据,大部分展示功能就完成了。然后在单独的Controller去处理一些特殊逻辑和表单接受就可以直接交差啦。

freemarker的自定义标签功能 是直接影响我开发模式的一种特性,利用这种特性,我直接将视图层做成通用分发规则,当需要哪些后台数据时,再使用自定义标签去 控制层回调数据过来。即做到了 MVC分层,也实现了数据调取的灵活性。
10 楼 wangpenghua 2014-12-14  

博主的例子我看都是动态的显示数据,而我们很多人用Freemarker是为了做静态化,Freemarker我接触也有两三年的时间了,我感觉挺好的,没有你说的那么一文不值。任何东西都不是完美无缺的。

相关推荐

    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