Use freemarker for static Web pages

Source: Internet
Author: User
Tags browser cache website performance

1. Introduction-What is freemarker?

Template engine: a common template-based tool used to generate output text.

Java-based Development kits and Class Libraries

2. Introduction-what can freemarker do?

View layer component in MVC Framework

Static HTML pages

Code Generation Tool

CMS template engine

Dynamic page Customization

3. Introduction-Why freemarker?

Separation of Program Logic (Java program) and page design (freemarker template)

Clear hierarchy, facilitating division of labor and cooperation

Excellent integration of mainstream web frameworks (struts2, springmvc)

Easy to learn and powerful functions

Free Open Source

4. Advantages of freemarker

Freemarker does not depend on servlet, network, or Web Environment

Freemarker was designed for MVC at the beginning and focuses only on presentation

You can load templates from any location; from the class path, from the database Medium

Easy to define special macros and functions

5. The freemarker is briefly described above. The following describes the static function of the freemarker practice web page.

The above introduction shows that freemarker is a template-based general tool used to generate output text. Therefore, we must customize the template that suits our own business and then generate the HTML page.

Freemarker uses freemarker. template. the configuration object loads the template (It also processes the creation and cache of the pre-resolution template), and then we get the template you want through the gettemplate method. Remember freemarker. template. configuration must be unique throughout your application.

5.1 In configuration, you can use the following methods to create three templates for loading.

void setDirectoryForTemplateLoading(File dir);

void setClassForTemplateLoading(Class cl, String prefix);

void setServletContextForTemplateLoading(Object servletContext, String path);

The first method above sets a clear directory on the disk's file system, which determines where the template is loaded. Not to mention the possibility. The file parameter must be an existing Directory. Otherwise, an exception is thrown.
The second method uses a class parameter and a prefix. This allows you to specify when to load Templates using the same mechanism, but to load classes using Java classloader. This means that
The input class parameter is used to call the class. getresource () method to locate the template. The prefix parameter adds a prefix to the Template Name. In the actual running environment, the class loading mechanism is the preferred method to load the template, because this mechanism is usually used to load files from the class path, it is safer and easier to load data from a specific directory in a file system. In the final application, it is good to use the. jar file for packaging all the code, so that you can directly execute the. jar file containing all the resources.
The third call method requires the context of the Web application and a base path as the parameter, which is the relative path of the Web application root path (the upper-level directory of the WEB-INF directory. The loader will open
Start to load the template. Although the loading method works for a. War file that is not packaged, it uses the servletcontext. getresource () method to access the template. Note that we refer to "directory" here ". If you skip the second folder or use a temporary folder, you can mix the static files (.html, .jpg, and so on) and. FTL files, but the. FTL file can be sent to the client for execution. Of course it must be in WEB-INF/web. configure a servlet in XML to process the URI format *. FTL user requests. Otherwise, the client cannot obtain the template. Therefore, you will see the confidential prompt content provided by the Web server. You cannot use an empty path in the site, which will become a problem and you should be in the WEB-INF
Store the template file somewhere in the directory, so that the template source file will not accidentally
Void setdirectoryfortemplateloading (File DIR );
Void setclassfortemplateloading (class Cl, string prefix );
Void setservletcontextfortemplateloading (Object
Servletcontext, string path );
This mechanism is very useful for servlet applications to load templates, and templates can be automatically updated without restarting web applications. However, for the class loading mechanism, this will not work.

5.2. Load templates from multiple locations

Import freemarker. cache. *; // The template loader is under this package... filetemplateloader ftl1 = new filetemplateloader (new file ("/tmp/templates"); filetemplateloader ftl2 = new filetemplateloader (new file ("/usr/data/templates ")); extends CTL = new classtemplateloader (getclass (), ""); templateloader [] loaders = new templateloader [] {ftl1, ftl2, CTL}; multitemplateloader MTL = new multitemplateloader (loaders ); cfg. settemplateloader (MTL );

Now, freemarker will try to load the template from the/tmp/templates directory. If the requested template is not found in this directory, it will continue to load from the/usr/data/templates directory. If the requested template is not found, it will use the class loader to load the template.

5.3 encapsulate freemarker for creating and loading templates

Package COM. ajun. template. utils; import Java. io. ioexception; import Java. io. writer; import Java. util. locale; import Java. util. map; import javax. servlet. servletcontext; import freemarker. template. configuration; import freemarker. template. defaultobjectwrapper; import freemarker. template. template; import freemarker. template. templateexception;/*** @ author ajun * @ http://blog.csdn.net/ajun_studio ***/Public clas S freemarkertutil {Private Static configuration Config = new configuration (); /*** @ Param templatename Template Name * @ Param root template root is used to output the result set in the template * @ Param out output object specific output location */public static void processtemplate (string templatename, map <?,?> Root, writer out) {try {// obtain template = config. gettemplate (templatename, "UTF-8"); // generate a file (Here we generate html) template. process (root, out); out. flush ();} catch (ioexception e) {e. printstacktrace ();} catch (templateexception e) {e. printstacktrace ();} finally {try {out. close (); out = NULL;} catch (ioexception e) {e. printstacktrace () ;}}/ *** initialize template configuration * @ Param servletcontext javax. servlet. servletcontext * @ Param templatedir template location */public static void initconfig (servletcontext, string templatedir) {config. setlocale (locale. china); config. setdefaultencoding ("UTF-8"); config. setencoding (locale. china, "UTF-8"); config. setservletcontextfortemplateloading (servletcontext, templatedir); config. setobjectwrapper (New defaultobjectwrapper ());}}

5.4 example

Use freemarker. jar to download it from Google.

In this example, freemarker will generate an HTML file that contains the header and tail of the HTML, and has the body. The three parts correspond to the three template files respectively, as shown below:

To output a result set in a template, use an El expression similar to $ {}

Header. FTL

companyName==>${h.companyName}<br/>address==>${h.address}<br/>

Footer. FTL

Des ==>$ {f. Des} <br/> <a href = "http: // localhost/htmlpage/updatefooter. Do"> Update footer </a>

Body. FTL, this template includes the above two template files

<! Doctype HTML public "-// W3C // dtd html 4.01 transitional // en"> <HTML> 

Three entity classes corresponding to the three templates

Footer. Java

package com.ajun.template.bean;/** * @author ajun * @http://blog.csdn.net/ajun_studio   **/public class Footer {private String des;public String getDes() {return des;}public void setDes(String des) {this.des = des;}}

Header. Java

package com.ajun.template.bean;/** * @author ajun * @http://blog.csdn.net/ajun_studio   **/public class Header {private String companyName;private String address;public String getCompanyName() {return companyName;}public void setCompanyName(String companyName) {this.companyName = companyName;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}}

User. Java

package com.ajun.template.bean;import java.util.Date;public class User {private Integer id;private String name ;private int age;private Date birthday;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public User(Integer id,String name, int age, Date birthday) {super();this.name = name;this.age = age;this.birthday = birthday;this.id = id;}public User() {super();}}

The following template provides some business logic operations for these three entity classes

Package COM. ajun. template. service; import COM. ajun. template. bean. footer;/*** @ author ajun * @ http://blog.csdn.net/ajun_studio ***/public class footerservice {Private Static footer F = new footer (); static {f. setdes ("Beijing-Langfang-good company !!!! Wow, haha !!! ");} Public static void Update (string des) {f. setdes (DES);} public static footer gerfooter () {return F ;}}

Package COM. ajun. template. service; import COM. ajun. template. bean. header;/*** @ author ajun * @ http://blog.csdn.net/ajun_studio ***/public class headerservice {Private Static header H = new header (); static {H. setaddress ("Beijing Chaoyang CBD"); H. setcompanyname ("Shanghai Tang Xiu !!! ");} Public static void Update (string address, string companyName) {H. setaddress (Address); H. setcompanyname (companyName);} public static header getheader () {return H ;}}
package com.ajun.template.service;import java.util.ArrayList;import java.util.Date;import java.util.List;import com.ajun.template.bean.User;/** * @author ajun * @http://blog.csdn.net/ajun_studio   **/public class UserService {private static List<User> users = new ArrayList<User>();static{for(int i=0;i<10;i++){User u = new User(i,"ajun"+i,i+10,new Date());users.add(u);}}public static List<User> getUsers(){return users;}public static void delete(int index){for(int i=0 ;i<users.size();i++){User u = users.get(i);if(u.getId()==index){users.remove(u);//users.remove(index);}}}}

The above mainly templates some of your business and Dao layer operations, so it does not involve database operations, mainly for experiments.

To generate an external call to HTML, freemarkertutil will be used. The code of this class has been given above.

Package COM. ajun. template. client; import Java. io. writer; import Java. util. hashmap; import Java. util. list; import Java. util. map; import COM. ajun. template. bean. footer; import COM. ajun. template. bean. header; import COM. ajun. template. bean. user; import COM. ajun. template. service. footerservice; import COM. ajun. template. service. headerservice; import COM. ajun. template. service. userservice; import COM. ajun. template. utils. freemarkertutil;/*** @ author ajun * @ http://blog.csdn.net/ajun_studio ***/public class processclient {Private Static Map <string, Object> root = new hashmap <string, Object> (); /*** call freemarkertutil. java * freemarkertutil. processtemplate ("body. FTL ", root, out); * to generate the HTML file * @ Param out */public static void processbody (writer out) {header H = headerservice. getheader (); root. put ("H", H); footer F = footerservice. gerfooter (); root. put ("F", f); List <user> Users = userservice. getusers (); root. put ("users", users); freemarkertutil. processtemplate ("body. FTL ", root, out );}}

At this point, I will provide a servlet. When the client initiates the first request, I will call this processclient to generate an HTML page. After each access, I can directly access HTML to achieve real static.

Package COM. ajun. template. servlet; import Java. io. file; import Java. io. fileoutputstream; import Java. io. ioexception; import Java. io. outputstreamwriter; import Java. io. writer; import javax. servlet. servletconfig; import javax. servlet. servletexception; import javax. servlet. HTTP. httpservlet; import javax. servlet. HTTP. httpservletrequest; import javax. servlet. HTTP. httpservletresponse; import COM. ajun. template. client. processclient; import COM. ajun. template. utils. directoryfilter; import COM. ajun. template. utils. freemarkertutil;/*** @ author ajun * @ http://blog.csdn.net/ajun_studio ***/public class index extends httpservlet {Private Static final long serialversionuid = 7474850489594441727l; Public index () {super ();} public void doget (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {This. dopost (request, response);} public void dopost (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {// path stored after HTML generation string dirpath = request. getsession (). getservletcontext (). getrealpath ("/templates/html"); File Path = new file (dirpath); // The Name Of The generated file: String indexfilename = "index.html "; /*** determine whether the HTML file exists. If the HTML file exists, access the HTML file directly without generating the HTML file */string [] indexfilelist = path. list (New directoryfilter (indexfilename); If (indexfilelist. length <= 0) {writer out = new outputstreamwriter (New fileoutputstream (dirpath + "/" + indexfilename), "UTF-8"); // generate the HTML file processclient. processbody (out); Request. getrequestdispatcher ("/templates/html/index.html "). forward (request, response);} else {request. getrequestdispatcher ("/templates/html/" + indexfilelist [0]). forward (request, response) ;}/ *** initialize the template configuration for later obtaining the template, loading in init is also mainly to ensure that the configuration instance is unique */Public void Init (servletconfig config) throws servletexception {string templatedir = config. getinitparameter ("templatedir"); freemarkertutil. initconfig (config. getservletcontext (), templatedir );}}

Web. xml configuration

<Servlet> <description> This is the description of my J2EE component </description> <display-Name> This is the display name of my J2EE component </display-Name> <Servlet -Name> index </servlet-Name> <servlet-class> COM. ajun. template. servlet. index </servlet-class> <init-param> <param-Name> templatedir </param-Name> template storage location, <param-value>/templates </param-value> </init-param> <load-on-startup> 3 </load-on- startup> Configure the initialization template at startup </servlet> <servlet-mapping> <servlet-Name> index </servlet-Name> <URL-pattern>/index. DO </url-pattern> </servlet-mapping>

Deploy it on Tomcat and enter http: // localhost/htmlpage/index. Do.

Page effect:

The page is ready, but the content is changed. What should I do? Here, when the list content changes, I delete the original HTML, use the template to regenerate the HTML page that meets the new results

When I delete one, I will regenerate the HTML page. But because of the browser cache, you deleted the page and re-generated the new HTML page. However, the browser still saves the original page, it won't work if you don't refresh twice,

Here, I will change the name of this HTML when I do not update it, so that the browser can load the latest one.

The specific delete operation is as follows:

Package COM. ajun. template. servlet; import Java. io. file; import Java. io. fileoutputstream; import Java. io. ioexception; import Java. io. outputstreamwriter; import Java. io. writer; import Java. util. UUID; import javax. servlet. servletexception; import javax. servlet. HTTP. httpservlet; import javax. servlet. HTTP. httpservletrequest; import javax. servlet. HTTP. httpservletresponse; import COM. ajun. template. client. processclient; import COM. ajun. template. service. userservice; import COM. ajun. template. utils. directoryfilter;/*** @ author ajun * @ http://blog.csdn.net/ajun_studio ***/public class deluser extends httpservlet {public void doget (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {This. dopost (request, response) ;}// delete user public void dopost (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {string id = request. getparameter ("ID"); userservice. delete (integer. valueof (ID); // generate the HTML location string dirpath = request. getsession (). getservletcontext (). getrealpath ("/templates/html"); // file name string indexfilename = "index.html"; // Delete the original file deloldhtml (dirpath, indexfilename); // prevents browser caching, used to regenerate the new htmluuid UUID = UUID. randomuuid (); writer out = new outputstreamwriter (New fileoutputstream (dirpath + "/" + UUID + indexfilename), "UTF-8"); processclient. processbody (out); response. sendredirect ("templates/html/" + UUID + "index.html ");} /*** Delete the original HTML file * @ Param htmldir * @ Param htmlname */private void deloldhtml (string htmldir, string htmlname) {File Path = new file (htmldir ); string [] indexfilelist = path. list (New directoryfilter (htmlname); If (indexfilelist. length> = 0) {for (string F: indexfilelist) {file Delf = new file (htmldir + "/" + F); Delf. delete ();}}}}

Through the above operations, every time the HTML is updated, the browser cache problem will not be solved.

Another tool class is the Java class that determines whether a specific HTML file has been generated.

Package COM. ajun. template. utils; import Java. io. file; import Java. io. filenamefilter;/*** @ author ajun * @ http://blog.csdn.net/ajun_studio ***/public class directoryfilter implements filenamefilter {string mystring; Public directoryfilter (string mystring) {This. mystring = mystring;} public Boolean accept (File Dir, string name) {// filenamefilter. accept (File Dir, string name) // test whether the specified file should be included in a file list. String F = new file (name). getname (); If (F. Contains (mystring) | f. Equals (mystring) {return true;} return false ;}}

Here the whole static update is complete. The static update mechanism is customized based on your own project business. You can generate HTML files at regular intervals or manually.

The project structure is as follows:

Remember: not all pages of a website need to be static, mainly because some data pages with low real-time performance are static (to speed up access ), others are implemented through pseudo-static, that is, rewrite utl.

Static pages are not the only way to improve website performance, but some cache products can also be used.

Common freemarker Resources

Official Website: http://www.freemarker.org/

Eclipse plug-in jbosstool: http://www.jboss.org/tools/download/

English document: https://sourceforge.net/projects/freemarker/files/chinese-manual/FreeMarker_Manual_zh_CN.pdf/download

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.