FreeMarker 是一個用 Java 語言編寫的模板引擎,它基於模板來生成文本輸出。FreeMarker與 Web 容器無關,即在 Web 運行時,它並不知道 Servlet 或 HTTP。它不只能夠用做表現層的實現技術,並且還能夠用於生成 XML,JSP 或 Java 等javascript
網頁靜態化技術和緩存技術的共同點都是爲了減輕數據庫的訪問壓力,可是具體的應用場景不一樣,緩存比較適合小規模的數據,而網頁靜態化比較適合大規模且相對變化不太頻繁的數據。另外網頁靜態化還有利於SEO。css
另外咱們若是將網頁以純靜態化的形式展示,就能夠使用Nginx這樣的高性能的web服務器來部署。Nginx能夠承載5萬的併發,而Tomcat只有幾百html
(1) assign指令java
1) 定義簡單類型angularjs
<#assign linkman="佩奇">
聯繫人:${linkman}
2) 定義對象類型web
<#assign info={"mobile":"13301231212",'address':'佩奇街'} >
電話:${info.mobile} 地址:${info.address}
(2) include指令spring
<#include "head.ftl">
(3) if指令數據庫
1) 在模板文件上添加spring-mvc
<#if success=true> 你已經過實名認證 <#else> 你未經過實名認證 </#if>
2) 在代碼中對str變量賦值緩存
在freemarker的判斷中,能夠使用= 也能夠使用==
map.put("success", true);
(4) list指令
若是想在循環中獲得索引,使用循環變量+_index就能夠獲得
<#list goodsList as goods>
${goods_index+1} 商品名稱: ${goods.name} 價格:${goods.price}<br>
</#list>
(5) 內建函數
共 ${goodsList?size} 條記錄
(6) 轉換JSON字符串爲對象
<#assign text="{'bank':'工商銀行','account':'10101920201920212'}" />
<#assign data=text?eval />
開戶行:${data.bank} 帳號:${data.account}
(7) 日期格式化
代碼 dataModel.put("today", new Date()); 在模板文件中加入 當前日期:${today?date} <br> 當前時間:${today?time} <br> 當前日期+時間:${today?datetime} <br> 日期格式化: ${today?string("yyyy年MM月")}
(8) 數字轉換爲字符串
代碼中對變量賦值: map.put("point", 102920122); 修改模板: 累計積分:${point}
(9) 空值處理運算符
1) 判斷某變量是否存在:「??」
用法爲:variable??,若是該變量存在,返回true,不然返回false
<#if aaa??> aaa變量存在 <#else> aaa變量不存在 </#if>
2) 缺失變量默認值:「!」
使用!對null值作轉換處理
${aaa!'-'}
(10) 運算符
1) 算數運算符
FreeMarker表達式中徹底支持算術運算,FreeMarker支持的算術運算符包括:+, - , * , / , %
2) 邏輯運算符
邏輯運算符有以下幾個: 邏輯與:&& 邏輯或:|| 邏輯非:! 邏輯運算符只能做用於布爾值,不然將產生錯誤
3) 比較運算符
表達式中支持的比較運算符有以下幾個: 1 =或者==:判斷兩個值是否相等. 2 !=:判斷兩個值是否不等. 3 >或者gt:判斷左邊值是否大於右邊值 4 >=或者gte:判斷左邊值是否大於等於右邊值 5 <或者lt:判斷左邊值是否小於右邊值 6 <=或者lte:判斷左邊值是否小於等於右邊值
注意: =和!=能夠用於字符串,數值和日期來比較是否相等,但=和!=兩邊必須是相同類型的值,不然會產生錯誤,並且FreeMarker是精確比較,"x","x ","X"是不等的.其它的運行符能夠做用於數字和日期,但不能做用於字符串,大部分的時候,使用gt等字母運算符代替>會有更好的效果,由於 FreeMarker會把>解釋成FTL標籤的結束字符,固然,也能夠使用括號來避免這種狀況,如:<#if (x>y)>
(1) 依賴
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> </dependency>
(2) applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.xxx.details.service.impl"></context:component-scan> <!-- freemarker --> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <!-- ftl文件存放路徑 -->
<property name="templateLoaderPath" value="/WEB-INF/ftl/" /> <property name="defaultEncoding" value="UTF-8" /> </bean> </beans>
(3) web.xml
<!-- 加載spring配置容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring/applicationContext-*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
(4) 生成靜態頁面的class
@Service public class ItemPageServiceImpl implements ItemPageService { private String "d:\\item\\";// 網頁生成目錄 @Autowired private FreeMarkerConfig freeMarkerConfig; @Autowired private TbGoodsMapper goodsMapper; @Autowired private TbGoodsDescMapper goodsDescMapper; @Override public boolean genItemHtml(Long goodsId){ try { Configuration configuration = freeMarkerConfig.getConfiguration(); Template template = configuration.getTemplate("item.ftl"); Map dataModel=new HashMap<>(); //1.加載商品表數據 TbGoods goods = goodsMapper.selectByPrimaryKey(goodsId); dataModel.put("goods", goods); //2.加載商品擴展表數據 TbGoodsDesc goodsDesc = goodsDescMapper.selectByPrimaryKey(goodsId); dataModel.put("goodsDesc", goodsDesc); Writer out=new FileWriter(pagedir+goodsId+".html"); template.process(dataModel, out); out.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } }
(5) ftl:/xxx-details-service/src/main/webapp/WEB-INF/ftl/item.ftl
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> <title>產品詳情頁</title> <link rel="icon" href="assets/img/favicon.ico"> <link rel="stylesheet" type="text/css" href="css/webbase.css" /> <link rel="stylesheet" type="text/css" href="css/pages-item.css" /> <link rel="stylesheet" type="text/css" href="css/pages-zoom.css" /> <link rel="stylesheet" type="text/css" href="css/widget-cartPanelView.css" /> <!-- angular --> <script type="text/javascript" src="plugins/angularjs/angular.min.js"></script> <!-- 自定義angular.js --> <script type="text/javascript" src="js/base.js"></script> <script type="text/javascript" src="js/controller/detailsController.js"></script> <!-- freemarker --> <script> var itemList = [ <#list itemList as item> { "id":${item.id?c}, "title":"${item.title!''}", "price":${item.price?c}, "spec": ${item.spec}, "num":${item.num?c}, "image":"${item.image}" }, </#list> ]; var specificationItems = ${goodsDesc.specificationItems}; </script> </head> <body ng-app="xxx" ng-controller="detailsController" ng-init="num=1;search()"> <!--頁面頂部 開始--> <#include "head.ftl"> <!-- 圖片列表 --> <#assign itemImages=goodsDesc.itemImages?eval> <!-- 擴展屬性列表 --> <#assign customAttributeItems=goodsDesc.customAttributeItems?eval> <!-- 規格列表 --> <#assign specificationItems=goodsDesc.specificationItems?eval> <!--頁面頂部 結束--> <div class="py-container"> <div id="item"> <div class="crumb-wrap"> <ul class="sui-breadcrumb"> <li> <a href="#">${itemCat1}</a> </li> <li> <a href="#">${itemCat2}</a> </li> <li class="active"><a href="#">${itemCat3}</a></li> </ul> </div> <!--product-info--> <div class="product-info"> <div class="fl preview-wrap"> <!--放大鏡效果--> <div class="zoom"> <!--默認第一個預覽--> <div id="preview" class="spec-preview"> <span class="jqzoom"> <#if itemImages?size gt 0> <img jqimg="${itemImages[0].url}" src="${itemImages[0].url}" width="400px" height="400px"/> </#if> </span> </div> <!--下方的縮略圖--> <div class="spec-scroll"> <a class="prev"><</a> <!--左右按鈕--> <div class="items"> <ul> <#list itemImages as image> <li> <img src="${image.url}" bimg="${image.url}" onmousemove="preview(this)" /> </li> </#list> </ul> </div> <a class="next">></a> </div> </div> </div> <div class="fr itemInfo-wrap"> <div class="sku-name"> <h4>{{item.title}}</h4> </div> <div class="news"><span>${goods.caption}</span></div> <div class="summary"> <div class="summary-wrap"> <div class="fl title"> <i>價 格</i> </div> <div class="fl price"> <i>¥</i> <em>{{item.price}}</em> <span>降價通知</span> </div> <div class="fr remark"> <i>累計評價</i><em>612188</em> </div> </div> <div class="summary-wrap"> <div class="fl title"> <i>促 銷</i> </div> <div class="fl fix-width"> <i class="red-bg">加價購</i> <em class="t-gray">滿999.00另加20.00元,或滿1999.00另加30.00元,或滿2999.00另加40.00元,便可在購物車換 購熱銷商品</em> </div> </div> </div> <div class="support"> <div class="summary-wrap"> <div class="fl title"> <i>支 持</i> </div> <div class="fl fix-width"> <em class="t-gray">以舊換新,閒置手機回收 4G套餐超值搶 禮品購</em> </div> </div> <div class="summary-wrap"> <div class="fl title"> <i>配 送 至</i> </div> <div class="fl fix-width"> <em class="t-gray">滿999.00另加20.00元,或滿1999.00另加30.00元,或滿2999.00另加40.00元,便可在購物車換購熱銷商品</em> </div> </div> </div> <div><h3>庫存數量: ${item.num}</h3></div> <div class="clearfix choose"> <div id="specification" class="summary-wrap clearfix"> <#list specificationItems as specificationItem> <!-- <dl ng-if="goods.tbGoodsDesc.specificationItems != null" ng-repeat="specificationItem in goods.tbGoodsDesc.specificationItems"> --> <dl> <dt> <div class="fl title"> <i>選擇${specificationItem.attributeName}</i> </div> </dt> <!-- <dd ng-repeat="attributeValue in specificationItem.attributeValue"> --> <#list specificationItem.attributeValue as attributeValue> <dd> <a href="javascript:void(0);" ng-click="changeItemId('${specificationItem.attributeName}', '${attributeValue}')" class="{{isDefault('${specificationItem.attributeName}', '${attributeValue}')?'selected':''}}">${attributeValue}<span title="點擊取消選擇"> </span></a> </dd> </#list> </dl> </#list> </div> <div class="summary-wrap"> <div class="fl title"> <div class="control-group"> <div class="controls"> <input autocomplete="off" type="text" value="1" minnum="1" class="itxt" ng-model="num"/> <a href="javascript:void(0)" class="increment plus" ng-click="addNum(1)">+</a> <a href="javascript:void(0)" class="increment mins" ng-click="addNum(-1)">-</a> </div> </div> </div> <div class="fl"> <ul class="btn-choose unstyled"> <li> <a href="javascript:void(0);" ng-click="addToCart()" class="sui-btn btn-danger addshopcar">加入購物車</a> </li> </ul> </div> </div> </div> </div> </div> </div> </div> <!-- 底部欄位 --> <!--頁面底部 開始 --> <#include "foot.ftl"> <!--頁面底部 結束 --> </body> </html>