原标题:使用FreeMarker替换JSP的10个理由
你还在使用 Java 服务器页面(俗称JSP)吗?我曾经也是,但是几年前我抛弃了它们,并且再也没有用过JSP了。JSP 是个很好的概念,但是它却剥夺了 web 开发的乐趣。 对我而言,这些都是小事,比如无法在页面模板上使用单独的文件header.jsp 和 footer.jsp,不能调用表达式语言的方法,在运行时无法合并,重新排列页面的各个部分。所以我转而使用 FreeMarker 模板。FreeMarker 已经存在一段时间了,如果你最近没有关注过 FreeMarker 的话,那这有些建议给你,让你考虑下个 web 应用使用 FreeMarker。
1、类加载没有 PermGen 问题如果你已经开发Java Web应用程序一段时间,那么对于 JVM 的 PermGen 问题可能并不陌生。由于 FreeMarker 模板不编译成类,它们不占用 PermGen 空间,并不需要一个新的类加载器加载。
2、模板加载器直接从数据源加载页面和模板岂不是很好?也许从 CMS 或数据库。也许你只想把它们放在一个地方,可以不重新部署整个应用程序就能更新它们。那么在 JSP 中你是很难做到这一点的,但 FreeMarker 提供的模板加载器就是为了 这个目的。你可以使用内建类或者创建你自己的实现。
- ClassTemplateLoader:从classpath中加载模板。
- FileTemplateLoader:在文件系统中从指定文件夹加载模板。
- StringTemplateLoader:从一个字符串 Map 中加载模板。
- URLTemplateLoader:从 URL 中加载模板。 你必须要实现 getURL 方法,但应该很容易做到。
- WebappTemplateLoader:从 servlet 上下文中加载模板。
FreeMarker 也可以将多个加载器链在一起形成一个系列模板装载器。我通常使用 WebappTemplateLoader 指向 WEB—INF 下一个内容文件夹。
Configuration configuration = new Configuration(); configuration.setTemplateLoader( new WebappTemplateLoader(servletContext, "WEB-INF/content"));3、可以在运行时嵌入模板
FreeMarker 能让你创建真正的模板,而不只是片段 ,还记得 JSP 中的 header 和 footer 吗?FreeMarker 允许你使用一个模板(在本例中为 head.ftl)
<head> <title>${title}</title> </head>
并将其添加到另一个模板(site.ftl body区域)。
<html> ${body} </html>
可以以编程的方式选择哪个模板进入 body 区。还可以添加多个模板一起放入同一区域。甚至可以将字符串值或计算的值放入 body 区域。在 JSP 中试试做到这些。
4、没有导入JSP 要求你导入每个你需要使用的类,就像一个常规的 Java 类一样。FreeMarker 模板,嗯,仅仅是模板。可以被包括在另一个模板中,但目前还不需要导入类。
5、支持 JSP 标签使用 Jsp 的一个理由是有可用性很好的标签库。好消息是 FreeMarker 支持 JSP 标签。坏消息是它们使用 FreeMarker 的语法,不是 JSP 语法。
6、表达式语言中的方法调用除非你的目标是 Servlet 3.0/El 2.2 标准的容器,那么表达式语言中方法调用是不可用的。不是所有人都同意 EL 表达式中方法调用是一件好事,但是当你需要它们的时候,使用 JSP 真的太痛苦了。 但是 FreeMarker 同等对待其中每个引用。
${customer.address.country}
${customer.getAddress().country}7. 内置空字符串处理
FreeMarker 和 Jsp 都可以在表达式语言中处理空值,但 FreeMarker 在可用性上更先进一些。
Invoice Date: ${(customer.invoice.date)!}
感叹号告诉 FreeMarker 对表达式自动检查 null 值和空字符串。如果 customer、invoice 或者 date 中有一个为空值或空字符串,你只会得到标签:
Invoice Date:
另一个选择是感叹号后包括你的默认值。
Invoice Date: ${(customer.invoice.date)!'No Invoice Available'}
如果所有值丢失,你会得到:
Invoice Date: No Invoice Available
请参见处理缺少的值了解更多细节。
8、共享变量FreeMarker 的共享变量是我最喜欢的“隐藏”功能之一。此功能可以让你设置自动添加到所有模板的值。 例如,可以设置应用程序的名称作为共享变量。
Configuration configuration = new Configuration(); configuration.setSharedVariable("app", "StackHunter");
然后像任何其他变量一样访问它。
App: ${app}
在过去使用共享变量一般引用照片包 然后使用像 ${i18n.resourceBundle.key} 这样的表达式来获取值。
${i18n.countries.CA} ${i18n.countries['CA']} ${i18n.countries[countryCode]}
上面这些行都引用 countries_en.properties 照片包内的 key “CA”对应的值。你需要执行自己的 TemplateHashModel,然后将其添加为一个共享变量来实现这一目标。
9、支持 JSONFreeMarker 内置 JSON 支持。 比方说你有以下的 JSON 存储到变量命名 user 的字符串中。
{ 'firstName': 'John', 'lastName': 'Smith', 'age': 25, 'address': { 'streetAddress': '21 2nd Street', 'city': 'New York', 'state': 'NY', 'postalCode': 10021 }}
使用 ?eval 将从字符串转换为一个 JSON 对象,然后像其他数据一样在表达式中使用。
<#assign user = user?eval> User: ${user.firstName}, ${user.address.city}10、不只是为了 Web 开发
最后,与 JSP 不同的是FreeMarker 模板可以在 servlet 容器之外使用。可以使用它们来生成电子邮件、 配置文件、 XML 映射等。你甚至可以使用它们来生成 web 页 并将它们保存在服务器端的缓存中。 请在下一个 web 项目尝试使用 FreeMarker把 web 开发的乐趣给找回来。
相关:
全球第一家口袋妖怪道馆将于 11 月 19 日,在日本大阪开张。 说起“道馆”,玩过游戏和看过动画的人可能第
想拥有明星般精致的五官吗?想打造标致的锥子脸吗?想知道完美面部比例的秘密吗?看完这篇牙齿矫正的文章…
物流毫无疑问是现在房地产市场里最火的版块,较低的地价,可观的租金,电商利好带来的持续需求,简单的运营
看到提问者对 MT 没什么概念,就在此叨逼一番。毕竟,要开好 MT,不能光靠经验。MT 不同于其他自动变速箱,
可瞧好了老爷车是不是都漂亮……无可否认 2CV 在汽车的历史上的重要地位。但是我还是得说:实在是太丑了。其
Magic Leap 目前还是一家只有预告片不见产品的神奇公司。他们号称做虚拟现实产品,因Google 的巨额投资而被估
上海市各月用电量可以在这里找到上海市发展和改革委员会,上海市从 2012 年 1 月到 2015 年 9 月各月的居民
亚马逊尝试了各种方式来送货,最近,它们又找来了每天清晨送报纸的卡车合作。在芝加哥,亚马逊推出了一个试
北京时间10月22日凌晨消息,苹果公司周三发布了正式版iOS 9.1操作系统,这是iOS 9在9月
因为喜欢户外多年,一直热爱登山,之前都是乱登山,这也是我们大部分驴友的通病,而不是科学的登山。而登山