10 Reasons to Replace Your JSPs With FreeMarker Templates
Still using Java Server Pages? I was too, but a few years ago I ditched them and haven’t looked back since. JSPs are a fine concept, but they take the joy out of web development. For me, it was the little things, like having to breakup my page templates into separate files:header.jsp and footer.jsp, not being able to call methods in the expression language, and not being able to combine and arrange page parts at runtime. FreeMarker templates are what I turned to. FreeMarker has been around for a while, but if you haven’t looked at them recently, here are a few reasons to consider them for your next web app.
1. No Classloading PermGen Issues
You’re probably no stranger to the JVM’s PermGen issues if you’ve developed Java web apps for a while. Since FreeMarker templates aren’t compiled to classes, they don’t take up permgen space and don’t require a new class loader to reload.
2. Template Loaders
Wouldn’t it be nice to load your pages and templates from a central place? Maybe from a CMS or database. Maybe you just want to put them on a file mount where they can be updated without redeploying the whole app. Well with JSPs you’re in for a hard time, but FreeMarker provides template loaders for just this purpose. You can create your own implementation or use one of the built-in classes.
- ClassTemplateLoader – loads templates from the classpath.
- FileTemplateLoader – loads templates from a specific folder in the file system.
- StringTemplateLoader – loads templates from a Map of strings.
- URLTemplateLoader – loads templates from a URL. You’ll have to implement thegetURL method, but that should be easy to do.
- WebappTemplateLoader – loads templates from a servlet context.
FreeMarker also has a multi loader to chain together a series of template loaders.
I typically use the WebappTemplateLoader to point to a content folder under WEB-INF.
Configuration configuration = new Configuration(); configuration.setTemplateLoader( new WebappTemplateLoader(servletContext, "WEB-INF/content"));
3. Templates Can Be Nested At Runtime
FreeMarker let’s you create real templates, not just fragments — remember the header and footer JSPs? It does this by allowing you to take one template (head.ftl in this case).
<head> <title>${title}</title> </head>
And add it to a placeholder of another template (the body region of site.ftl).
<html> ${body} </html>
You can choose which template goes into the body region programmatically. You can also add multiple templates together into the same region. You can even put a string or calculated value into the body region instead. Try doing that in a JSP.
4. No Imports
JSPs requires you to import every class you intend to use, just like a regular Java class. FreeMarker templates on-the-other-hand are just, well, templates. You can include one template in another, but there are no classes that need to be imported.
5. Supports JSP Tags
One argument for using JSPs is the availability of tag libraries out there. The good news is that FreeMarker supports JSP tags. The bad news is they’re referenced using FreeMarker syntax, not JSP syntax.
6. Method Calls in the Expression Language
Unless you’re targeting a Servlet 3.0/EL 2.2 container, method calls in the expression language are out. Not everyone agrees that method calls in the EL are a good thing, but when you really need them, the JSP workarounds were painful.
FreeMarker, however, treats each of these references the same.
${customer.address.country}
7. Built-in Null And Empty String Handling
Both FreeMarker and JSPs can handle null values in their expression languages, but FreeMarker goes a step further in usability.
Invoice Date: ${(customer.invoice.date)!}
The exclamation symbol tells FreeMarker to do automatic null and empty string checking on the attached expression. If any of customer, invoice, or date are either null or empty string, you’ll just get the label:
Invoice Date:
Another option is to include your default text after the exclamation.
Invoice Date: ${(customer.invoice.date)!'No Invoice Available'}
Again, if any of the values are missing, you get back:
Invoice Date: No Invoice Available
See Handling missing values for more details.
8. Shared Variables
FreeMarker’s shared variables are one of my favourite “hidden” features. This feature let’s you set values that are automatically added to all templates.
For example you can set your app’s name as a shared variable.
Configuration configuration = new Configuration();
configuration.setSharedVariable("app", "StackHunter");
Then access it like any other variable.
App: ${app}
I’ve used shared variables in the past to reference resource bundles using expressions like${i18n.resourceBundle.key}.
${i18n.countries.CA}
${i18n.countries['CA']}
${i18n.countries[countryCode]}
The above lines all refer to the the key “CA” inside the countries_en.properties resource bundle. You’ll need to implement your own TemplateHashModel then add it as a shared variable to achieve this.
9. JSON Support
FreeMarker has built-in JSON support.
Let’s say you have the following JSON stored as a String in variable named user.
{ 'firstName': 'John', 'lastName': 'Smith', 'age': 25, 'address': { 'streetAddress': '21 2nd Street', 'city': 'New York', 'state': 'NY', 'postalCode': 10021 }}
Use ?eval to convert it from a string to a JSON object, then use it in expressions as you would any other data.
<#assign user = user?eval> User: ${user.firstName}, ${user.address.city}
10. Not Just for the Web
Finally, unlike JSPs, FreeMarker templates can be used outside of a servlet container. You can use them to generate emails, config files, XML mapping, etc. You can even use them to generate and save your web pages in a server-side cache.
Try using FreeMarker on your next web project and put the fun back into web development.
Original: http://blog.stackhunter.com/2014/01/17/10-reasons-to-replace-your-jsps-with-freemarker-templates/
posted on 2014-06-20 12:20 malcolmshen 阅读(233) 评论(0) 收藏 举报
浙公网安备 33010602011771号