Statement: This article is from: http://blog.csdn.net/ajun_studio/article/details/6932185/
1. Introduction - What is FreeMarker
Template Engine: A Template-based Common Tool for Generating Output Text
Based on Java Development kits and class libraries
2. Introduction - What FreeMarker Can Do
View Layer Components in MVC Framework
Static Html pages
Code Generation Tool
CMS Template Engine
Dynamic customization of page columns
3. Introduction - Why use FreeMarker
Separation of Program Logic (Java Program) and Page Design (FreeMarker Template)
Clear layers are conducive to division of labour and cooperation
Good integration of mainstream Web frameworks (struts 2, spring mvc)
Easy to learn and powerful
Free and open source
4. Advantages of FreeMarker
FreeMarker does not depend on Servlet, network or Web environments
FreeMarker was originally designed for MVC and focused only on presentation.
You can load templates from anywhere; from the classpath, from the data base secondary
Easy to define ad hoc macrosum functions
5. The above is a brief introduction to Freemarker. The following is mainly to use the static function of Freemarker internship web page.
From the introduction above, we know that Freemarker is a template-based general tool for generating output text, so we have to customize the template that suits our business, and then generate our html pages.
Freemarker loads templates through the freemarker.template.Configuration object (it also handles creating and caching pre-parsing templates), and then we get the template you want through the getTemplate method. One thing to remember is that freemarker.template.Configuration must guarantee a unique instance throughout your application.
5.1. In Configuration, the following methods can be used to facilitate the establishment of three template loads
-
void setDirectoryForTemplateLoading(File dir);
-
void setClassForTemplateLoading(Class cl, String prefix);
-
void setServletContextForTemplateLoading(Object servletContext, String path);
The first method described above sets up a clear directory on the disk's file system, which determines where to load the template. Don't say it's possible, the File parameter must be an existing directory. Otherwise, an exception will be thrown.
The second invocation method uses a Class type parameter and a prefix. This lets you specify when to load templates through the same mechanism, but using Java lassLoader to load classes. This means transmission.
The incoming Class parameter is used to call the Class.getResource() method to find the template. The prefix parameter prefixes the name of the template. In the actual running environment, class loading mechanism is the preferred method to load templates, because it is usually safer and simpler to load files from the classpath than from the specific directory location of the file system. In the final application, it's also good to package all the code in A. jar file so that the user can directly execute the. jar file containing all the resources.
The third method of invocation requires the context of the Web application and a base path, which is the relative path of the Web application root path (the directory of the WEB-INF directory). Then the loader will be opened from the Web application directory
Start loading the template. Although the loading method works for unpackaged. war files, because it uses the ServletContext.getResource() method to access templates, note that we mean "directories" here. If the second parameter is omitted (or used"), then static files (. html,. jpg, etc.) and. FTL files can be mixed, but. FTL files can be sent to the client for execution. Of course, you have to configure a Servlet in WEB-INF/web.xml to process URI format as *.ftl
User requests, otherwise the client can not get the template, so you will see the content of the secret prompt given by the Web server. You can't use empty paths in your site. This will be a problem. You should store template files somewhere in the WEB-INF directory so that template source files are not accidental.
void setDirectoryForTemplateLoading(File dir);
void setClassForTemplateLoading(Class cl, String prefix);
void setServletContextForTemplateLoading(Object
servletContext, String path);
To be implemented, this mechanism is a very useful way for servlet applications to load templates, and templates can be automatically updated without restarting Web applications, but for class loading mechanisms, this is not feasible.
5.2. Loading templates from multiple locations
-
import freemarker.cache.*;
-
...
-
FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates"));
-
FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates"));
-
ClassTemplateLoader 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 templates from the / tmp/templates directory. If no requested templates are found in this directory, it will continue to try to load templates from the / usr/data/templates directory. If no requested templates are found, it will use a class loader to load templates.
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;
-
-
-
-
-
-
public class FreeMarkertUtil {
-
-
private static Configuration config = new Configuration();
-
-
-
-
-
-
-
public static void processTemplate(String templateName, Map<?,?> root, Writer out){
-
try{
-
-
Template template=config.getTemplate(templateName,"utf-8");
-
-
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();
-
}
-
}
-
}
-
-
-
-
-
-
public static void initConfig(ServletContext 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. Introduction of Examples
Use freemarker.jar to download it on your own google.
In this example, we will generate an HTML file by Freemarker, including the head and tail of html, already body. These three parts will correspond to three template files respectively, as follows:
To output a result set within a template, ${} can be output using an EL-like expression
header.ftl
-
companyName==>${h.companyName}<br/>
-
address==>${h.address}<br/>
footer.ftl
-
des==>${f.des}<br/>
-
-
<a href="http://Localhost/htmlpage/Update Footer.do"> Update Footer</a>
body.ftl, this template include s the above two template files
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-
<html>
-
<head>
-
<title>User List</title>
-
-
<meta http-equiv="pragma" content="no-cache">
-
<meta http-equiv="cache-control" content="no-cache">
-
<meta http-equiv="expires" content="0">
-
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
-
<meta http-equiv="description" content="This is my page">
-
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-
<!--
-
<link rel="stylesheet" type="text/css" href="styles.css">
-
-->
-
-
</head>
-
-
<body>
-
<#include "header.ftl" parse=true encoding="utf-8">
-
<hr/>
-
<a href="#">User List </a> <br/>"
-
<table border="1">
-
<tr>
-
<td>User name</td>
-
<td>Age</td>
-
<td>Birthday</td>
-
<td>id</td>
-
<td>operation</td>
-
</tr>
-
<#list users as user>
-
<tr>
-
<td>${user.name}</td>
-
<td>${user.age}</td>
-
<td>
-
${user.birthday?string("yyyy-MM-dd HH:mm:ss")}
-
</td>
-
<td>${user.id}</td>
-
<td><a href="http://Localhost/htmlpage/DelUser.do?Id=${user.id}">Delete</a></td>
-
</tr>
-
</#list>
-
-
</table>
-
<hr/>
-
<#include "footer.ftl" parse=true encoding="utf-8">
-
</body>
-
</html>
Three entity classes corresponding to the three templates
Footer.java
-
package com.ajun.template.bean;
-
-
-
-
-
-
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;
-
-
-
-
-
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 contains some business logic operations for these three entity classes
-
package com.ajun.template.service;
-
-
import com.ajun.template.bean.Footer;
-
-
-
-
-
public class FooterService {
-
-
private static Footer f = new Footer();
-
static{
-
f.setDes("Beijing-Langfang-Good company!!!! Wow ha ha!!!");
-
}
-
-
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;
-
-
-
-
-
public class HeaderService {
-
-
private static Header h = new Header();
-
-
static{
-
h.setAddress("Beijing Chaoyang CBD");
-
h.setCompanyName("Shanghai Tangxiu!!!");
-
}
-
-
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;
-
-
-
-
-
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);
-
-
}
-
}
-
}
-
}
The above is mainly the template for some of your business and dao layer operations, so there is no database operations involved, mainly for experiments.
The method of generating html external calls will use the class FreeMarkertUtil, which 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;
-
-
-
-
-
-
public class ProcessClient {
-
-
private static Map<String,Object> root = new HashMap<String,Object>();
-
-
-
-
-
-
-
-
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 to call the ProcessClient to generate the html page when the client makes the first request, and then every time I visit it, I can directly access the html to make it truly 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;
-
-
-
-
-
-
public class Index extends HttpServlet {
-
-
private static final long serialVersionUID = 7474850489594438527L;
-
-
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 {
-
-
String dirPath = request.getSession().getServletContext().getRealPath("/templates/html");
-
File path = new File(dirPath);
-
-
String indexFileName = "index.html";
-
-
-
-
String[] indexfileList = path.list(new DirectoryFilter(indexFileName));
-
if(indexfileList.length<=0){
-
Writer out = new OutputStreamWriter(new FileOutputStream(dirPath+"/"+indexFileName),"UTF-8");
-
-
ProcessClient.processBody(out);
-
request.getRequestDispatcher("/templates/html/index.html").forward(request, response);
-
}else{
-
request.getRequestDispatcher("/templates/html/"+indexfileList[0]).forward(request, response);
-
}
-
-
-
}
-
-
-
-
-
-
-
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 is based on app Root directory
-
<param-value>/templates</param-value>
-
</init-param>
-
<load-on-startup>3</load-on-startup>Initialize template configuration for startup
-
</servlet>
-
-
<servlet-mapping>
-
<servlet-name>Index</servlet-name>
-
<url-pattern>/Index.do</url-pattern>
-
</servlet-mapping>
Deploy to tomcat, enter:
http://localhost/htmlpage/Index.do
Page effect:
The page is ready, but the content has changed, how to update it? I am here when the list content changes, I delete the original html, use the template and then regenerate the HTML page that conforms to the new results.
When I delete a page, I will regenerate the html page, but because of the browser cache, that is, you deleted and regenerated the new html page, but the browser still saved the original page, not refreshed twice.
When I don't update the html, I will rename it so that the browser can load the latest html.
The specific deletion operations are 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;
-
-
-
-
-
public class DelUser extends HttpServlet {
-
-
-
public void doGet(HttpServletRequest request, HttpServletResponse response)
-
throws ServletException, IOException {
-
this.doPost(request, response);
-
}
-
-
-
public void doPost(HttpServletRequest request, HttpServletResponse response)
-
throws ServletException, IOException {
-
-
String id = request.getParameter("id");
-
UserService.delete(Integer.valueOf(id));
-
-
-
String dirPath = request.getSession().getServletContext().getRealPath("/templates/html");
-
-
String indexFileName = "index.html";
-
-
-
delOldHtml(dirPath,indexFileName);
-
-
-
UUID uuid = UUID.randomUUID();
-
Writer out = new OutputStreamWriter(new FileOutputStream(dirPath+"/"+uuid+indexFileName),"UTF-8");
-
ProcessClient.processBody(out);
-
response.sendRedirect("templates/html/"+uuid+"index.html");
-
}
-
-
-
-
-
-
-
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();
-
}
-
}
-
}
-
-
}
With the above operation, every time html is updated, the problem of browser caching can not be solved.
Another tool class that needs to be introduced 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;
-
-
-
-
-
public class DirectoryFilter implements FilenameFilter {
-
-
String myString;
-
public DirectoryFilter(String myString)
-
{
-
this.myString = myString;
-
}
-
-
public boolean accept(File dir,String name)
-
{
-
-
String f= new File(name).getName();
-
if(f.contains(myString) || f.equals(myString)){
-
return true;
-
}
-
return false;
-
}
-
-
}
At this point, the whole static is completed. The static update mechanism is customized according to the business of your own project. It can generate html files regularly or manually.
The project structure chart is as follows:
Remember: not all pages of a website need to be static, mainly some data pages with low real-time performance need to be static (to improve access speed), others are achieved through pseudo-static, that is, to rewrite utl.
Page static is not the only way to improve the performance of the website, but also can be achieved by some caching products.
Common FreeMarker Resources
Official website home page: http://www.freemarker.org/
Eclipse plug-in JbossTool: http://www.jboss.org/tools/download/
Chinese Documents: https://sourceforge.net/projects/freemarker/files/chinese-manual/FreeMarker_Manual_zh_CN.pdf/download