天天看點

SpringBoot2 整合FreeMarker模闆,完成頁面靜态化處理一、頁面靜态化二、流程分析三、代碼實作案例四、源代碼位址

一、頁面靜态化

1、動靜态頁面

靜态頁面

即靜态網頁,指已經裝載好内容HTML頁面,無需經過請求伺服器資料和編譯過程,直接加載到客戶浏覽器上顯示出來。通俗的說就是生成獨立的HTML頁面,且不與伺服器進行資料互動。

優缺點描述:

  • 靜态網頁的内容穩定,頁面加載速度極快;
  • 不與伺服器互動,提升安全性;
  • 靜态網頁的互動性差,資料實時性很低;
  • 次元成本高,生成很多HTML頁面;

動态頁面

指跟靜态網頁相對的一種網頁程式設計技術,頁面的内容需要請求伺服器擷取,在不考慮緩存的情況下,服務接口的資料變化,頁面加載的内容也會實時變化,顯示的内容卻是随着資料庫操作的結果而動态改變的。

  • 動态網頁的實時擷取資料,延遲性低;
  • 依賴資料庫互動,頁面維護成本很低;
  • 與資料庫實時互動,安全控制的成本高;
  • 頁面加載速度十分依賴資料庫和服務的性能;

動态頁面和靜态頁面有很強的相對性,對比之下也比較好了解。

2、應用場景

動态頁面靜态化處理的應用場景非常多,例如:

  • 大型網站的頭部和底部,靜态化之後統一加載;
  • 媒體網站,内容經過渲染,直接轉為HTML網頁;
  • 高并發下,CDN邊緣節點代理的靜态網頁;
  • 電商網站中,複雜的産品詳情頁處理;

靜态化技術的根本:提示服務的響應速度,或者說使響應節點提前,如一般的流程,頁面(用戶端)請求服務,服務處理,響應資料,頁面裝載,一系列流程走下來不僅複雜,而且耗時,如果基于靜态化技術處理之後,直接加載靜态頁面,好了請求結束。

二、流程分析

靜态頁面轉換是一個相對複雜的過程,其中核心流程如下:

SpringBoot2 整合FreeMarker模闆,完成頁面靜态化處理一、頁面靜态化二、流程分析三、代碼實作案例四、源代碼位址
  • 開發一個頁面模闆,即靜态網頁樣式;
  • 提供接口,給頁面模闆擷取資料;
  • 頁面模闆中編寫資料接口返參的解析流程;
  • 基于解析引擎,把資料和頁面模闆合并;
  • 頁面模闆内容加載完成後轉換為HTML靜态頁面;
  • HTML靜态頁面上傳到檔案伺服器;
  • 用戶端(Client)擷取靜态頁面的url加載顯示;

主流程大緻如上,如果資料接口響應參數有變,則需要重新生成靜态頁,是以在資料的加載實時性上面會低很多。

三、代碼實作案例

1、基礎依賴

FreeMarker是一款模闆引擎:即一種基于模闆和要改變的資料,并用來生成輸出文本(HTML網頁、電子郵件、配置檔案、源代碼等)的通用工具。

<dependency>           
&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
&lt;artifactId&gt;spring-boot-starter-freemarker&lt;/artifactId&gt;                

</dependency>

2、頁面模闆

這裡既使用FreeMarker開發的模闆樣式。

<html>
<head>           
&lt;title&gt;PageStatic&lt;/title&gt;                

</head> <body> 主題:${myTitle}<br/> <#assign text="{'auth':'cicada','date':'2020-07-16'}" /> <#assign data=text?eval /> 作者:${data.auth} 日期:${data.date}<br/> <table class="table table-striped table-hover table-bordered" id="editable-sample">

&lt;thead&gt;
&lt;tr&gt;
    &lt;th&gt;規格描述&lt;/th&gt;
    &lt;th&gt;産品詳情&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
         &lt;#list tableList as info&gt;
         &lt;tr class=""&gt;
             &lt;td&gt;${info.desc}&lt;/td&gt;
             &lt;td&gt;&lt;img src="${info.imgUrl}" height="80" width="80"&gt;&lt;/td&gt;
         &lt;/tr&gt;
         &lt;/#list&gt;
&lt;/tbody&gt;                

</table><br/> <#list imgList as imgIF>

&lt;img src="${imgIF}" height="300" width="500"&gt;                

</#list> </body> </html>

FreeMarker的文法和原有的HTML文法基本一緻,但是具有一套自己的資料處理标簽,用起來不算複雜。

3、解析過程

通過解析,把頁面模闆和資料接口的資料合并到一起即可。

@Service
public class PageServiceImpl implements PageService {           
private static final Logger LOGGER = LoggerFactory.getLogger(PageServiceImpl.class) ;
private static final String PATH = "/templates/" ;

@Override
public void ftlToHtml() throws Exception {
    // 建立配置類
    Configuration configuration = new Configuration(Configuration.getVersion());
    // 設定模闆路徑
    String classpath = this.getClass().getResource("/").getPath();
    configuration.setDirectoryForTemplateLoading(new File(classpath + PATH));
    // 加載模闆
    Template template = configuration.getTemplate("my-page.ftl");
    // 資料模型
    Map&lt;String, Object&gt; map = new HashMap&lt;&gt;();
    map.put("myTitle", "頁面靜态化(PageStatic)");
    map.put("tableList",getList()) ;
    map.put("imgList",getImgList()) ;
    // 靜态化頁面内容
    String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
    LOGGER.info("content:{}",content);
    InputStream inputStream = IOUtils.toInputStream(content,"UTF-8");
    // 輸出檔案
    FileOutputStream fileOutputStream = new FileOutputStream(new File("F:/page/newPage.html"));
    IOUtils.copy(inputStream, fileOutputStream);
    // 關閉流
    inputStream.close();
    fileOutputStream.close();
}

private List&lt;TableInfo&gt; getList (){
    List&lt;TableInfo&gt; tableInfoList = new ArrayList&lt;&gt;() ;
    tableInfoList.add(new TableInfo(Constant.desc1, Constant.img01));
    tableInfoList.add(new TableInfo(Constant.desc2,Constant.img02));
    return tableInfoList ;
}

private List&lt;String&gt; getImgList (){
    List&lt;String&gt; imgList = new ArrayList&lt;&gt;() ;
    imgList.add(Constant.img02) ;
    imgList.add(Constant.img02) ;
    return imgList ;
}                

}

生成後的HTML頁面直接使用浏覽器打開即可,不再需要依賴任何資料接口服務。

四、源代碼位址

GitHub·位址
        https://github.com/cicadasmile/middle-ware-parent               
GitEE·位址
        https://gitee.com/cicadasmile/middle-ware-parent               

SpringBoot2 整合FreeMarker模闆,完成頁面靜态化處理一、頁面靜态化二、流程分析三、代碼實作案例四、源代碼位址

<dependency>           
&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
&lt;artifactId&gt;spring-boot-starter-freemarker&lt;/artifactId&gt;                

</dependency>

<html>
<head>           
&lt;title&gt;PageStatic&lt;/title&gt;                

</head> <body> 主題:${myTitle}<br/> <#assign text="{'auth':'cicada','date':'2020-07-16'}" /> <#assign data=text?eval /> 作者:${data.auth} 日期:${data.date}<br/> <table class="table table-striped table-hover table-bordered" id="editable-sample">

&lt;thead&gt;
&lt;tr&gt;
    &lt;th&gt;規格描述&lt;/th&gt;
    &lt;th&gt;産品詳情&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
         &lt;#list tableList as info&gt;
         &lt;tr class=""&gt;
             &lt;td&gt;${info.desc}&lt;/td&gt;
             &lt;td&gt;&lt;img src="${info.imgUrl}" height="80" width="80"&gt;&lt;/td&gt;
         &lt;/tr&gt;
         &lt;/#list&gt;
&lt;/tbody&gt;                

</table><br/> <#list imgList as imgIF>

&lt;img src="${imgIF}" height="300" width="500"&gt;                

</#list> </body> </html>

@Service
public class PageServiceImpl implements PageService {           
private static final Logger LOGGER = LoggerFactory.getLogger(PageServiceImpl.class) ;
private static final String PATH = "/templates/" ;

@Override
public void ftlToHtml() throws Exception {
    // 建立配置類
    Configuration configuration = new Configuration(Configuration.getVersion());
    // 設定模闆路徑
    String classpath = this.getClass().getResource("/").getPath();
    configuration.setDirectoryForTemplateLoading(new File(classpath + PATH));
    // 加載模闆
    Template template = configuration.getTemplate("my-page.ftl");
    // 資料模型
    Map&lt;String, Object&gt; map = new HashMap&lt;&gt;();
    map.put("myTitle", "頁面靜态化(PageStatic)");
    map.put("tableList",getList()) ;
    map.put("imgList",getImgList()) ;
    // 靜态化頁面内容
    String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
    LOGGER.info("content:{}",content);
    InputStream inputStream = IOUtils.toInputStream(content,"UTF-8");
    // 輸出檔案
    FileOutputStream fileOutputStream = new FileOutputStream(new File("F:/page/newPage.html"));
    IOUtils.copy(inputStream, fileOutputStream);
    // 關閉流
    inputStream.close();
    fileOutputStream.close();
}

private List&lt;TableInfo&gt; getList (){
    List&lt;TableInfo&gt; tableInfoList = new ArrayList&lt;&gt;() ;
    tableInfoList.add(new TableInfo(Constant.desc1, Constant.img01));
    tableInfoList.add(new TableInfo(Constant.desc2,Constant.img02));
    return tableInfoList ;
}

private List&lt;String&gt; getImgList (){
    List&lt;String&gt; imgList = new ArrayList&lt;&gt;() ;
    imgList.add(Constant.img02) ;
    imgList.add(Constant.img02) ;
    return imgList ;
}                

}

GitHub·位址
        https://github.com/cicadasmile/middle-ware-parent               
GitEE·位址
        https://gitee.com/cicadasmile/middle-ware-parent