Velocity 与 FreeMarker 概述和优劣分析

来源:互联网 发布:unity3d ugui 动画 编辑:程序博客网 时间:2024/06/14 11:39

This story appeared on JavaWorld at http://www.javaworld.com/javaworld/jw-11-2007/jw-11-java-template-engines.html Velocity or FreeMarker? Two open source Java-based template engines compared By Jeroen van Bergen, JavaWorld.com, 11/29/07 Template engines can be applied to a wide variety of development scenarios where you want to generate text based on specific processing rules, and are often used as the view component in MVC applications. In this article, Jeroen van Bergen explains where template engines fit into your application architecture and shows you some of the operations common to all template engines. Finally, he compares the two leading Java template engines, Velocity and FreeMarker, in terms of power, ease of use, and performance. Template engines are used in Java development scenarios where it is necessary to automatically generate text and format it according to specific processing rules. The two most popular open source Java template engines are Velocity and FreeMarker. While Velocity has been the leading template engine for a long time, FreeMarker has begun to overtake it, offering a speed and sophistication you won't always find in Velocity. In this article I briefly introduce you to template engines, explaining where they fit into your Java application architecture and showing you some basic operations common to them all. I then compare Velocity and FreeMarker based on power, ease of use, and performance. This discussion is primarily intended for readers new to template engines who want to learn what they're used for and get some help choosing between the two leading open source options. What is a template engine? A template engine is a component that takes fixed text and data as input, integrates these following certain processing rules, and outputs a text document containing the data. Template engines are very useful for tasks such as creating dynamic Web pages, documents, and e-mails, and can also be used to generate source code. Template engines are used mostly as the view component in an MVC architecture. The template engine encourages good separation between the actual view logic and the rendered view, which is considered a Good Thing. Using a template engine involves some overhead in building the application, but most developers see a quick return on investment when the application has to be changed. The separation of view from the logic makes it easy to update the look and feel of the application by adjusting the templates, rather than having to re-write the source code. The relationship is similar to that of CSS and HTML, where a change in style requires a small edit to the CSS file, rather than many revisions to the HTML. Overview of open source Java template engines As is often the case when developing on the Java platform, you have many Java-based template engines to choose from. I have tried to compile a comprehensive list of all Java template engines that are currently available. Some of these are real template engines in the sense that they have not been developed with a certain kind of application in mind. Some are specialized engines that aim to do a specific kind of document creation, such as decorating Web pages. If a template engine is not meant for general-purpose use you'll see an explicit description of the type of application it's intended for. Table 1. Template engines for the Java platform Name Version Purpose URL License Velocity 1.5 General-purpose template engine http://velocity.apache.org/ Apache Software License FreeMarker 2.3.10 General-purpose template engine http://www.freemarker.org/index.html BSD License SiteMesh 2.3 Web page layout and decoration http://www.opensymphony.com/sitemesh OpenSymphony License TeaServlet 2.3 Web pages http://teatrove.sourceforge.net Tea License Jamon 2.3.0 General-purpose template engine http://www.jamon.org/index.html Mozilla Public License WebMacro General-purpose template engine http://www.webmacro.org/ GNU General Public License What can I do with a template engine? Many applications that create output do so based on a certain template, though it might be known under another name, such as "report design" or "master page." Because a generic template engine is capable of creating any type of text document, the range of usage scenarios is wide. Template engines are most popularly used for creating HTML, in some variant or another, as the view in an MVC architecture. Creating a document always involves merging data and a template. The template is static, the data is dynamic. After processing the data and the template the template engine produces an output document. Based on the instructions in the template all or some of the data provided will be part of the output. Usually, you will provide the data to the template engine in the form of a collection or container, such as a HashMap. Most template engines provide special classes for this, commonly named context or model. FreeMarker provides a SimpleHash class (among others), Velocity offers a VelocityContext class for feeding data to the template engine. Types of output Creating other types of text documents besides HTML is easy, but you must take care with some of these formats. For instance, it can be tricky to create RTF documents in Velocity because the ${} notation has special meanings in RTF docs and Velocity, respectively. Subsequently, you have to escape the processing instructions recognized by the document format in the right way in order to avoid nasty surprises in the final document. Generally speaking, RTF is a hard format to use. The only editors that seem to completely understand this format are full-blown word processors like Microsoft Word. Other file formats, such as ODF, are easier to deal with. Any file format consisting of plain text is easily generated using a template engine. As a general rule you might say that the closer a format is to plain text, the easier it is to create it with a template engine. XML is one example of a format that is very basic, with no real formatting or embedded processing instructions. As such it is an ideal candidate to generate with a template engine. Basic operations Now that you have an idea of what you can do with a template engine, let's take a look at some of the basic operations involved. A Velocity template for generating the mandatory "Hello World!" output might look like this: Hello, ${engineName} world! If you supply Velocity with the value for the engineName token, Velocity will replace the token in the template with that value and write the result of the merge to the output. A template engine can do much more than straightforward token replacement, however. Looping, for instance: #foreach($engineName in $engineNames) Hello, ${engineName} world! #end This code will produce a document that contains a line for every engineName that is present in the engineNames collection. You can also do conditional processing with template engines: #if ($engineName = "Velocity") Hello, $engineName world! #else Hello, other world! #end This code will produce output only if the engineName is Velocity. Including other content in a template is also a basic operation, as shown here: #include("header.txt") Hello $engineName world! #include("footer.txt") Next we'll take a closer look at two of the most popular template engines. Velocity and FreeMarker Velocity and FreeMarker are the two template engines that seem to enjoy the most widespread use. Both are general-purpose template engines, so if you want to evaluate them for use in your projects you should look at a number of criteria. In the next sections I'll compare Velocity and FreeMarker in terms of power, ease of use, and performance. In some cases these criteria juxtapose each other; for instance, power often diminishes ease of use. The ideal balance between these is of course subjective. You may require a level of fine-grained control that justifies many Off switches, whereas someone else could be happy with just one On/Off button. Power A simple "Hello World!" template is no problem for any template engine. The more interesting features can be found in Velocity and FreeMarker's inclusion and macro functions. Another important consideration is the way the template engine allows you to manipulate variable data while merging data and the template. Table 2 compares the features found in FreeMarker and Velocity. Table 2. FreeMarker and Velocity compared Feature FreeMarker Velocity Iteration Yes Yes Conditional processing Yes Yes Macros Yes Yes Includes other templates Yes Yes Parses included templates Yes Yes Executes embedded Java code No Only if the objects are available in the context supplied to Velocity FreeMarker is stricter than Velocity. Velocity allows references to non-existing properties, and will even do so silently if the template designer wishes. FreeMarker is more formal and will generate a null pointer exception and at least log it. The macro capabilities of FreeMarker are more sophisticated: macros can be called recursively. In general, FreeMarker offers more functionality to template designers, such as breaking out of loops, detecting if the current iteration is the last in a loop, and comparing date and time values. FreeMarker also allows you to use multiple namespaces for variables, which is handy for structuring libraries of macros. On the other hand, you may not require so much sophistication from a template engine, and the learning curve for FreeMarker is a little steeper than the one for Velocity. You can enhance Velocity with components that provide specialized functionality. For example, Texen embeds Velocity in an Ant task, and Anakia can be used to transform XML documents. Ease of use A number of factors contribute to ease of use. I'll look at three: ease of install, consistency of the API, and the quality of the documentation. Installing both Velocity and FreeMarker is easy: just download the current version and install it in your directory of choice. This procedure should look familiar to anyone who has ever included a library in a project. Velocity depends on a number of other libraries, which are included in the distribution. The API documentation of both Velocity and FreeMarker is available in API doc format. Both come with an overview of the template language, which is aimed at template designers, and a developer's guide, which is aimed at programmers who want to use the template engine as an application component. The basic usage pattern of both is very simple: instantiate an engine or template, feed it the data, and call a parse function to create the output. Both template engines support the use of the Writer interface to write the output to, giving you a wide range of options to capture the output. FreeMarker also offers a conversion tool to convert Velocity templates to FreeMarker templates. This will save you a lot of time if you end up migrating from Velocity to FreeMarker. Both FreeMarker and Velocity sport resource loaders, which are classes providing functionality to load templates and other resources from a number of locations like the file system or an HTTP server. These can be useful when building an application that uses a large number of templates that are stored in some organized manner. Applications that use only one or two templates can just as easily do their own resource management and pass the template as a String to the engine. Performance The performance of any template engine depends on the surrounding application as much as the template engine itself. An application can help the template engine achieve maximum throughput. Consider caching the contents of templates in memory, especially if you're not using the engine's inclusion feature. I did not concern myself with the surrounding application while doing performance measurement because I wanted to focus on the performance of the template engine itself. I measured performance as elapsed wall time to accomplish a certain task. Since a template engine will always have a certain overhead associated with instantiation and initialization I tried to isolate the startup overhead from the measurements. Most overhead was encountered during the first parse of a template. I performed a number of different tests, trying to cover most usage scenarios for a template engine. I ran all the tests using the IntelliJ IDEA 5.1 on Windows XP, using the Sun JRE v5. The relevant hardware specs are the CPU (AMD Mobile Athlon 3000+) and memory (512 MB of RAM). No special JVM parameters were used. Both engines can be quite fast, so I measured not just the creation of a single output document, but the creation of thousands of outputs. To skip the overhead I started measuring just before the first call to parse the template. I measured in milliseconds, using the System.currentTimeMillis() call. Results are shown in Table 3. Table 3. Performance measurement Template FreeMarker Velocity Hello World! 110 141 Big Template 11647 32317 In conclusion Both FreeMarker and Velocity are very capable template engines. Velocity seems to enjoy a larger user base, probably due to the fact that it is part of the Apache project. As I've shown in this article, though, FreeMarker is the more sophisticated and faster of the two. In basic operations both template engines are almost similar, providing an API that is easy to understand. Both Velocity and FreeMarker are fairly easy to integrate into an application and offer good performance on small templates. Velocity slows down when parsing larger templates, which you might take into account when choosing a template engine for your project. About the author Jeroen van Bergen started working in information technology in 1993. He has worked in the fields of billing, systems integration, and order management in the telecommunication industry. He has been programming in Java since 2000. Jeroen is at the moment mainly interested in workflow, Java-XML binding, and automatic document generation using Velocity and XSL:FO. All contents copyright 1995-2010 Java World, Inc. http://www.javaworld.com