對FreeMarker技術的思考
依照靜態非靜態來劃分網頁分為兩種:靜態網頁和非靜態網頁,究其優缺點而言,靜態網頁在用戶訪問的時候響應快,可是因為裏面的數據是寫死的。所以致命的缺陷就是數據不能動態顯示。非靜態頁面(如jsp)數據能夠動態顯示,能夠這樣理解,這種頁面就是顯示數據的一個模板,可是因為在用戶請求得到響應曾經。server端須要將其解析為瀏覽器可識別的html語言。這個解析過程須要耗費時間(尤其頁面數據量大的時候。耗費的時間會很多其它),所以致命的缺陷就是請求發出後響應的過程較慢。那麽有沒有一種方法或工具自己主動生成靜態網頁呢?答案是肯定的。今天談一下對FreeMarker的認識:
1、什麽是FreeMarker:
FreeMarker是一個用Java語言編寫的模板引擎。通過模板(擴展名為“ftl”的文件)生成靜態的網頁,從而提高訪問站點的用戶體驗。
2、普通情況下什麽時候使用FreeMarker:
一般使用FreeMarker生成門戶站點的靜態文件。
3、如何使用FreeMarker:
樣例1:
a、下載FreeMarker相關jar包:http://download.csdn.net/detail/wangshuxuncom/7592455
b、新建所須要的模板——index.ftl:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" dir="ltr"> <head> <title>首頁</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> </head> <body> <center style="margin-top: 21%;"><font style="color: red;font-size: 39pt;font-weight: bold;">${message}</font></center> </body> </html>
package com.ghj.packageofservlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class IndexServlet extends HttpServlet { private static final long serialVersionUID = 1714787202664419914L; public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("message", "歡迎進入系統。!d、將FreeMarker相關jar包導入新建的系統中。並配置web.xml文件:。"); request.getRequestDispatcher("index.ftl").forward(request, response); } }
<?e、公布project。在http中輸入“http://127.0.0.1:8080/project名/IndexServlet”就可以看到效果。xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>freemarker</servlet-name> <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class> <!-- FreemarkerServlet settings: --> <init-param> <param-name>TemplatePath</param-name><!-- 指定模板的路徑 --> <param-value>/</param-value> </init-param> <init-param> <param-name>NoCache</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>ContentType</param-name><!-- 設置生成html文件的編碼方式。 --> <param-value>text/html; charset=UTF-8</param-value> </init-param> <!-- FreeMarker settings: --> <init-param> <param-name>template_update_delay</param-name><!-- template_update_delay用來指定更新模版文件的間隔時間,相當於多長時間檢測一下是否有必要又一次載入模版文件,0 表示每次都又一次載入,否則為多少毫秒鐘檢測一下模版是否更改。 --> <param-value>0</param-value> </init-param> <init-param> <param-name>default_encoding</param-name><!-- 設置模板文件的編碼方式。 --> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>number_format</param-name> <param-value>0.##########</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>freemarker</servlet-name> <url-pattern>*.ftl</url-pattern> </servlet-mapping> <servlet> <servlet-name>IndexServlet</servlet-name> <servlet-class>com.ghj.packageofservlet.IndexServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>IndexServlet</servlet-name> <url-pattern>/IndexServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
說明:在這個project中,ftl文件充當了類似於jsp的角色。
【0分下載該樣例】
樣例2:
a、下載FreeMarker相關jar包:http://download.csdn.net/detail/wangshuxuncom/7592455
b、新建所須要的模板——index.html(註意:非“ftl”):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" dir="ltr"> <head> <title>首頁</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> </head> <body> <center style="margin-top: 21%;"><font style="color: red;font-size: 39pt;font-weight: bold;">${message}</font></center> </body> </html>c、新建一個Servlet——IndexServlet:
package com.ghj.packageofservlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class IndexServlet extends HttpServlet { private static final long serialVersionUID = 1714787202664419914L; public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("message", "歡迎進入系統!!。"); request.getRequestDispatcher("index.html").forward(request, response);//非“index.html”非“index.ftl” } }d、將FreeMarker相關jar包導入新建的系統中,並配置web.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>freemarker</servlet-name> <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class> <!-- FreemarkerServlet settings: --> <init-param> <param-name>TemplatePath</param-name><!-- 指定模板的路徑 --> <param-value>/</param-value> </init-param> <init-param> <param-name>NoCache</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>ContentType</param-name><!-- 設置生成html文件的編碼方式。 --> <param-value>text/html; charset=UTF-8</param-value> </init-param> <!-- FreeMarker settings: --> <init-param> <param-name>template_update_delay</param-name><!-- template_update_delay用來指定更新模版文件的間隔時間。相當於多長時間檢測一下是否有必要又一次載入模版文件,0 表示每次都又一次載入。否則為多少毫秒鐘檢測一下模版是否更改。 --> <param-value>0</param-value> </init-param> <init-param> <param-name>default_encoding</param-name><!-- 設置模板文件的編碼方式。 --> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>number_format</param-name> <param-value>0.##########</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>freemarker</servlet-name> <url-pattern>*.html</url-pattern><!-- 非“*.ftl” --> </servlet-mapping> <servlet> <servlet-name>IndexServlet</servlet-name> <servlet-class>com.ghj.packageofservlet.IndexServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>IndexServlet</servlet-name> <url-pattern>/IndexServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>e、公布project。在http中輸入“http://127.0.0.1:8080/project名/IndexServlet”就可以看到效果;
說明:在這個project中。html文件充當了類似於jsp的角色;本樣例和上面的代碼基本一樣,不同點在於:上一個樣例模板的文件類型為ftl,而本樣例為html——這說明一點:僅僅要配置得當,模板未必僅僅能是ftl類型的文件。
【0分下載該樣例】
總結:
1、上面兩個樣例大同小異,看完上面樣例之後大家可能會有疑問:上面兩個樣例中,從client請求的發出到client看到結果整個過程是如何的呢?嗯嗯嗯,這確實是一個須要搞清楚的問題:向IndexServlet發出請求——>IndexServlet接收請求並將模板和模板所需數據作為響應——>FreemarkerServlet接收IndexServlet發出的請求並將數據“填充”到模板對應的位置,然後將響應返回client——>客戶看到結果。
2、個人感覺假設用FreeMarker單純去實現上面的樣例,覺得有點兒大材小用,或者說有點兒“屈才”——假設要實現上面的功能。直接使用諸如jsp的非靜態頁面豈不不更好,FreeMarker的看家本事是生成諸如HTML格式的靜態頁面(且看以下樣例)。
樣例3:
a、下載FreeMarker相關jar包:http://download.csdn.net/detail/wangshuxuncom/7592455
b、新建所須要的模板——index.ftl:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" dir="ltr"> <head> <title>首頁</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> </head> <body> <center style="margin-top: 21%;"><font style="color: red;font-size: 39pt;font-weight: bold;">${message}</font></center> </body> </html>
c、新建一個創建HTML靜態頁面工具類——FreemarkerUtil:
package com.ghj.packageoftool; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Map; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; /** * Freemarker工具類 * * @author GaoHuanjie */ public class FreemarkerUtil { /** * 創建靜態HTML文件 * * @param templateFilePath 模板文件存放的路徑 * @param templateFileName 模板文件名 * @param htmlFilePath 靜態文件(即HTML文件)保存路徑 * @param htmlFileName 所生成靜態文件(即HTML文件)的名稱 * @param propMap 用於處理模板的屬性Object映射 * * @return boolean 靜態文件創建成功返回true,否則返回false */ public boolean createHtmlFile(String templateFilePath, String templateFileName, String htmlFilePath, String htmlFileName, Map<String, Object> propMap){ try { Configuration configuration = new Configuration(); configuration.setDefaultEncoding("UTF-8"); configuration.setDirectoryForTemplateLoading(new File(templateFilePath)); //configuration.setClassForTemplateLoading(this.getClass(), "/ftl");//假設模板文件在src的某個包內,請將上一行代碼凝視掉而使用該代碼。ftl代表包名。 Template template = configuration.getTemplate(templateFileName, "UTF-8");//確保模板中的中文在生成靜態文件裏不變成亂碼。File createHTMLFilePath = new File(htmlFilePath); if (!createHTMLFilePath.exists()) {//假設保存靜態文件(即HTML文件)的根路徑不存在,則創建該文件夾。 createHTMLFilePath.mkdirs(); } Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(htmlFilePath + "/" + htmlFileName)), "UTF-8"));//防止數據(propMap)中的中文在靜態頁面中變為亂碼。 template.process(propMap, writer);//生成靜態文件 writer.flush(); writer.close(); } catch (TemplateException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } catch (Exception e) { e.printStackTrace(); return false; } return true; } }
d、新建一個創建HTML靜態頁面監聽器——CreatHtmlListener:
package com.ghj.packageoflistener; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import com.ghj.packageoftool.FreemarkerUtil; /** * 創建HTML靜態頁面監聽器 * * @author GaoHuanjie */ public class CreatHtmlListener implements ServletContextListener { public void contextDestroyed(ServletContextEvent event) { //event.getServletContext().log("創建HTML靜態頁面監聽器銷毀!!!"); } public void contextInitialized(ServletContextEvent event) { FreemarkerUtil freemarkerUtil = new FreemarkerUtil(); String templateFilePath = event.getServletContext().getRealPath("/")+"templates"; String templateFileName = "index.ftl"; String htmlFilePath = event.getServletContext().getRealPath("/"); String htmlFileName = "index.html"; Map<String, Object> propMap = new HashMap<String, Object>(); propMap.put("message", "Hello,歡迎進入系統!。!"); if(freemarkerUtil.createHtmlFile(templateFilePath, templateFileName, htmlFilePath, htmlFileName, propMap)){ event.getServletContext().log("HTML靜態頁面創建完畢!!!"); } } }
e、將FreeMarker相關jar包導入新建的系統中。並配置web.xml文件:
<?xml version="1.0" encoding="UTF-8"?
> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <listener> <listener-class>com.ghj.packageoflistener.CreatHtmlListener</listener-class> </listener> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
f、公布project。在http中輸入“http://127.0.0.1:8080/project名”就可以看到效果。
說明:在這個project中,創建HTML靜態頁面的監聽器在project被Tomcat公布時被運行而且index.html被創建,在實際應用中某些門戶站點生成靜態頁面的時機並不像該監聽器寫的那樣——往往在監聽器中加入一個定時器,在特定的時間點更新靜態網頁。以使client可以看到最新的內容,我不知道大家留意過沒有。門戶站點首頁內容更新並非那麽的頻繁。【0分下載該樣例】
對FreeMarker技術的思考