freemarker入門、freemarker語法、spring與freemarker的整合、網頁靜態化方案分析

freemarker入門

上節課我們一起學習瞭如何在查詢商品詳情時添加緩存,這節課我們一起來學習下freemarker。

我們都知道,緩存可以提高查詢性能,但是當用戶訪問量很大時,單純依靠緩存已經不行了,爲什麼這麼說呢?這是因爲我們在訪問商品詳情的時候由於每款商品都不一樣,因此每款商品的詳情頁都是動態生成的,每查看一次,頁面就要重新渲染一次,渲染的過程是消耗時間的,當用戶訪問量很大時,這便在一定程度上降低了系統性能。那麼怎麼解決這個問題呢?這便引出了我們今天要學習的內容–“網頁靜態化”,所謂網頁靜態化,是指我們根據一定的模板,事先把要展示的頁面生成靜態頁面,存放到服務器,當用戶訪問某商品詳情頁時便可以直接從服務器獲取相應的靜態頁,不用重新渲染,這就在很大程度上提升了系統性能。

那麼用什麼技術來實現靜態化呢?目前常用的兩種技術是volocity和freemarker,我們學習其中最流行的freemarker。那麼什麼是freemarker?

FreeMarker是一款模板引擎: 即一種基於模板和要改變的數據,並用來生成輸出文本(HTML網頁、電子郵件、配置文件、源代碼等)的通用工具。它不是面向最終用戶的,而是一個Java類庫,是一款程序員可以嵌入他們所開發產品的組件。

FreeMarker是免費的,基於Apache許可證2.0版本發佈。其模板編寫爲FreeMarker Template Language(FTL),屬於簡單、專用的語言。需要準備數據在真實編程語言中來顯示,比如數據庫查詢和業務運算,之後模板顯示已經準備好的數據。在模板中,主要用於如何展現數據,而在模板之外注意於要展示什麼數據。

我們來看一張圖,如下圖所示,FreeMarker將模板和動態數據組合在一起,生成一個靜態頁面。

Template:<html>hello ${name}!</html>
Java objects:model.setName(''world");
Output:<html>hello world!</html>

下面我們便使用FreeMarker進行相應的測試,要想在工程中使用FreeMarker便要添加對FreeMarker的依賴,靜態頁面最好放到表現工程,因此我們在taotao-item-web工程的pom.xml文件中添加對FreeMarker的依賴,如下圖所示(在taotao-parent工程統一定義了FreeMarker的版本)

下面我們創建一個模板(模板的擴展名隨意,只是習慣性的用.ftl來命名)

創建一個測試類TestFreeMarker.java

需要注意的是,靜態頁面輸出路徑E:/freemarker/out要確保存在

我們運行上面的那個測試方法,運行成功後,在E:/freemarker/out目錄下便可以看到hello.html靜態html,我們雙擊打開它,可以在瀏覽器中看到hello freemarker信息,這就是我們要在模板中展示的內容,這說明模板與動態內容結合成功了!!

freemarker語法

要學習freemarker就要學習它的語法,下面我們便依次來學習freemarker的常用語法。
第一個語法:Pojo的使用
首先創建一個Pojo類Student
下面我們便針對這個Pojo來創建一個新的模板student.ftl 模板代碼如下:
下面對上節課的測試類代碼做下修改,
運行上面的測試方法後會在E:/freemarker/out/目錄下生成一個student.html頁面,我們雙擊在瀏覽器中查看,發現出現亂碼了。
這是由於文件的編碼格式不是utf-8造成的,原來的編碼是GBK,而我們的代碼中設置的編碼格式是UTF-8,因此需要將文件的編碼格式也變成UTF-8
然後我們再重新運行上面的測試方法,然後重新刷新頁面,可以看到亂碼解決了。而且我們可以正常看到Pojo類中的信息了。

第二種語法:循環
在測試類中添加一個集合,在模板中循環遍歷這個集合
模板添加的代碼如下,循環的語法是"<#"後面接集合,"as stu"中的"stu"是當前循環到的對象
添加完代碼之後,運行測試方法,成功後,我們再刷新靜態網頁,如下圖所示。正常展示出了學生列表。

第三種語法:循環下標的獲取
對於列表展示,如果我們想獲取行的下標的話,用freemarker很容易實現,爲了直觀的查看下標,我們在模板的列表展示中添加一列"序號",值的話就直接使用當前對象及下劃線和index如下圖所示,便可以獲取。${stu_index}
修改完後,我們重新運行測試方法,然後重新刷新靜態頁面,可以看到正確展示出了每行的下標。

第四種語法:if條件的使用
在列表展示當中經常用到隔行變色的效果,隔行變色就要用到if判斷,如果是奇數行就用某種顏色,偶數行就用另外一種顏色。比如我現在想把奇數行背景顏色變爲紅色,把偶數行背景顏色變爲藍色,語法是"<#if"後面加判斷條件,else在if條件之間(這點與我們平時的java習慣不一致)else書寫語法是<#else>,如下圖所示。
修改完後重新運行測試方法,然後重新刷新靜態頁面,可以看到已經展現出隔行變色的效果了。

第五種語法:日期處理
我們先來看默認情況下日期的展示效果,在測試類中添加一行代碼(把日期加入map當中),在模板中把日期取出來,如下圖所示。

修改完後,運行代碼,會看到如下圖所示的錯誤,告訴我們無法將日期轉換爲string類型,並且在"Tip"當中告訴了我們可以通過在date後面加?date或?time或?datetime來將日期類型轉換爲string。

既然告訴了我們應該怎麼辦,我們就按照上面的提示,先在模板的date後面加?date,如下所示。

日期處理類型:${date?date}
修改完後運行測試方法,然後重新刷新靜態網頁,可以看到如下圖所示界面,在頁面最下方展示出了日期,只是日期的格式是以"-"分隔的。

我們還可以把date後面換成?time和?datetime,這樣輸出的日期分別爲"21:12:23"和"2017-5-16 21:12:50"。可以發現,展示的日期格式是比較固定的,那麼如果我們想按自己想要的方式展示日期,該怎麼辦?這個其實剛纔報錯信息中已經給出提示信息了,如下圖所示,明確的告訴了我們可以在date後面加?string(‘yyyy/MM/dd HH:mm:ss’)來展示我們的日期。

模板中date展示改成如下代碼
日期處理類型:${date?string(‘yyyy/MM/dd HH:mm:ss’)}重新運行測試方法並重新刷新靜態網頁,如下圖所示,發現正常按照我們的想法進行展示了。

第六種語法:null值的處理
在頁面展示時有可能遇到null的處理,如果我們展示一個不存在的變量的話,就會變錯,如下圖所示,在最下方添加展示不存在的變量。
運行測試代碼,會出現運行錯誤,錯誤消息提示展示的內容是null或者不存在,要解決這個問題,“Tip"給出了提示信息,告訴我們可以在變量後面加”!默認值"。
模板對於變量的展示做以下修改:null值的處理:${var!“默認值”}
運行測試方法並重新刷新靜態頁面,如下圖所示。正常展示出了"默認值"。
還有一種處理null值的方法是使用if判斷。
使用if判斷null值:
<#if val??>
var是有值的
<#else>
var是Null
</#if>
運行測試代碼,然後重新刷新靜態頁面,可以看到輸出了"var是Null"。
我們現在讓var變量有值,方法是在測試方法中添加data.put(“var”,“123”);
運行測試方法然後重新刷新靜態頁面,可以看到var已經有值了。

第七種語法:添加頁眉頁腳
靜態頁面中最常見的是頁眉和頁腳的內容是固定的,這意味着我們不必要重複寫頁眉頁腳,只需要各寫一遍,然後需要的時候引入進來就可以了。我們舉個例子,把上節課寫的模板作爲頁腳添加進來。
重新運行測試方法,然後重新刷新靜態頁面,如下圖所示,可以看到正常展示出頁腳內容了。
有了這些語法,我們便可以製作出各種各樣的模板了。

spring與freemarker的整合

spring要與freemarker整合的話,需要兩個包,一個是freemarker的jar包,另一個是spriing-context-support的Jar包,需要在taotao-item-web工程中確保對兩個包的依賴
我們的taotao-item-web工程已經添加過對這兩個包的依賴了,因此我們不必關心這步了。

下面我們需要在taotao-item-web工程的spriingmvc.xml文件中添加關於freemarker的配置,如下圖所示。

下面寫一個Controller類HtmlGenController.java

寫完了代碼,現在我們測試一下該方法是否能成功,我們先啓動各個服務(zookeeper服務、image服務、solr服務、redis服務、activemq服務),然後依次啓動taotao-manager、taotao-content、taotao-search、taotao-manager-web、taotao-portal-web、 taotao-search-web、taotao-item-web工程。啓動完後,我們在地址欄輸入http://localhost:8086/genhtml.html並回車,即可看到頁面輸出"OK"

我們到E盤的freemarker/out目錄下查看生成的test.html,雙擊它在瀏覽器中查看,可以看到"spriing freemarker test"。

這就是freemarker與spring的簡單結合

網頁靜態化方案分析

我們要做到網頁靜態化,那麼需要有一套方案來操作。

首先是靜態網頁的名稱,要知道,每個商品的詳情頁面都是不一樣的,因此我們最好把商品的ID加".html"作爲靜態網頁的名稱。

接着,靜態網頁的生成時機是什麼?其中一種方案是當用戶點擊商品詳情的時候生成靜態頁面,但是這種情況是有嚴重問題的,當併發量高時,第一個人點擊商品詳情,然後去生成靜態頁面,有可能靜態頁面在生成的過程中有另外一個人也要訪問這個商品詳情頁面,這時程序判斷有沒有這個商品的靜態頁面,發現有了,就去展示,但其實這時靜態頁面還沒有生成完呢,這樣就會造成頁面不全的問題。另一種方案是當添加商品的時候就生成靜態頁面,這樣有足夠的時間來生成這個靜態頁面,後續有人訪問該商品詳情的時候,就可以直接查看靜態頁面了。

接着,靜態網頁生成的目錄應該放到哪兒?其中一種方案是將生成的靜態頁面放到webapp目錄下,這種方案不太好,原因是tomcat處理靜態頁面不是它的強項,處理jsp纔是它的強項。另外一種方案是使用http服務器,http服務器又可以分爲多種,其中一種Http服務器便是Apache服務器,另外一種http服務器可以使用nginx。

經過上面的方案分析,我們可以使用如下圖所示的流程,商品服務(taotao-manager)添加商品的時候發佈topic消息到消息隊列,server1和server2是兩套http服務器,這樣做的好處是提高系統的可用性,server1或server2從消息隊列中去獲取消息,知道添加了商品,於是生成這個商品的靜態頁面並且放到http服務器上,當用戶訪問的時候通過nginx反向代理服務器(後面會學習nginx)訪問其中一臺http服務器,從中獲取靜態頁面進行展示。

用戶—>反向代理服務器nginx—>
server1(taotao-item-web html目錄 http服務器nginx)
<----訂閱topic item-add-topic<----activemq消息隊列<—item-add-topic發送消息<----server2 taotao-manager
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章