靜態化?
這裏我們以網頁靜態化技術之一的Freemarker 爲例子。以電商爲原型
對於電商網站的商品詳情頁來說,至少幾百萬個商品,每個商品又有大量的信息,這樣的情況同樣也適用於使用網頁靜態化來解決
網頁靜態化技術和緩存技術的共同點都是爲了減輕數據庫的訪問壓力,但是具體的應用場景不同,緩存比較適合小規模的數據,而網頁靜態化比較適合大規模且相對變化不太頻繁的數據。另外網頁靜態化還有利於SEO。
另外我們如果將網頁以純靜態化的形式展現,就可以使用Nginx這樣的高性能的web服務器來部署。Nginx可以承載5萬的併發,而Tomcat只有幾百。
那什麼是 Freemarker?
FreeMarker 是一個用 Java 語言編寫的模板引擎,它基於模板來生成文本輸出。
FreeMarker與 Web 容器無關,即在 Web 運行時,它並不知道 Servlet 或 HTTP。
它不僅可以用作表現層的實現技術,而且還可以用於生成 XML,JSP 或 Java 等
Freemarker入門
Test.ftl
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入門小DEMO </title>
</head>
<body>
<#--我只是一個註釋,我不會有任何輸出 -->
${name},你好。${message}
<h3>assigne指令</h3>
<#assign linkman="周先生">
聯繫人:${linkman}
<#assign info={"mobile":"13301231212",'address':'北京市昌平區王府街'} >
電話:${info.mobile} 地址:${info.address}
<h3>if指令</h3>
<#if success=true>
你已通過實名認證
<#else>
你未通過實名認證
</#if>
<h3>list指令</h3>
----商品價格表----<br>
<#list goodsList as goods>
${goods_index+1} 商品名稱: ${goods.name} 價格:${goods.price}<br>
</#list>
<h3>內建函數</h3>
<h4>獲取集合大小</h4>
共 ${goodsList?size} 條記錄
<h4>轉換JSON字符串爲對象</h4>
<#assign text="{'bank':'工商銀行','account':'10101920201920212'}" />
<#assign data=text?eval />
開戶行:${data.bank} 賬號:${data.account}
<h4>日期格式化</h4>
當前日期:${today?date} <br>
當前時間:${today?time} <br>
當前日期+時間:${today?datetime} <br>
日期格式化: ${today?string("yyyy年MM月")}
<h4>數字轉換爲字符串</h4>
累計積分:${point}
累計積分:${point?c}
<h3>空值處理運算符</h3>
<h4>判斷某變量是否存在:“??”</h4>
<#if aaa??>
aaa變量存在
<#else>
aaa變量不存在
</#if>
<h4>缺失變量默認值:“!”</h4>
${aaa!'-'}
<h3>運算符</h3>
<h4>算數運算符</h4>
FreeMarker表達式中完全支持算術運算,FreeMarker支持的算術運算符包括:+, - , * , / , %
<h4>邏輯運算符</h4>
邏輯運算符有如下幾個:
邏輯與:&&
邏輯或:||
邏輯非:!
邏輯運算符只能作用於布爾值,否則將產生錯誤
<h4>比較運算符</h4>
表達式中支持的比較運算符有如下幾個:
1 =或者==:判斷兩個值是否相等.
2 !=:判斷兩個值是否不等.
3 >或者gt:判斷左邊值是否大於右邊值
4 >=或者gte:判斷左邊值是否大於等於右邊值
5 <或者lt:判斷左邊值是否小於右邊值
6 <=或者lte:判斷左邊值是否小於等於右邊值
注意: =和!=可以用於字符串,數值和日期來比較是否相等,但=和!=兩邊必須是相同類型的值,否則會產生錯誤,而且FreeMarker是精確比較,"x","x ","X"是不等的.其它的運行符可以作用於數字和日期,但不能作用於字符串,大部分的時候,使用gt等字母運算符代替>會有更好的效果,因爲 FreeMarker會把>解釋成FTL標籤的結束字符,當然,也可以使用括號來避免這種情況,
</body>
</html>
Demo001
package com.javaxl.freemarker;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class Demo001 {
public static void main(String[] args) throws IOException, TemplateException {
// 1.創建配置類
Configuration configuration = new Configuration(Configuration.getVersion());
// 2.設置模板所在的目錄
configuration.setDirectoryForTemplateLoading(
new File("E:\\y2---study2\\javaxl_lunece_freemarker\\src\\main\\resources"));
// 3.設置字符集
configuration.setDefaultEncoding("utf-8");
// 4.加載模板
Template template = configuration.getTemplate("test.ftl");
// 5.創建數據模型
Map map = new HashMap();
map.put("name", "小李飛刀 ");
map.put("message", "歡迎來到神奇的博客網站:http://www.javaxl.com!");
map.put("success", true);
List goodsList=new ArrayList();
Map goods1=new HashMap();
goods1.put("name", "蘋果");
goods1.put("price", 5.8);
Map goods2=new HashMap();
goods2.put("name", "香蕉");
goods2.put("price", 2.5);
Map goods3=new HashMap();
goods3.put("name", "橘子");
goods3.put("price", 3.2);
goodsList.add(goods1);
goodsList.add(goods2);
goodsList.add(goods3);
map.put("goodsList", goodsList);
map.put("today", new Date());
map.put("point", 102920122);
// 6.創建Writer對象
Writer out = new FileWriter(new File("E:\\y2---study2\\javaxl_lunece_freemarker\\src\\main\\webapp\\freemarker\\test.html"));
// 7.輸出
template.process(map, out);
// 8.關閉Writer對象
out.close();
}
}
效果圖
將網頁靜態化用於博客網站
數據庫:
blogDetail.ftl
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Python Django 模板層(AJAX)-javaxl-曉碼閣-博客專欄</title>
<link rel="stylesheet" href="./freemarkerDemo_files/bootstrap.min.css">
<link rel="stylesheet"
href="./freemarkerDemo_files/bootstrap-theme.min.css">
<link rel="stylesheet" href="./freemarkerDemo_files/blog.css">
<script src="./freemarkerDemo_files/jquery-1.11.2.min.js.下載"></script>
<script src="./freemarkerDemo_files/bootstrap.min.js.下載"></script>
<style type="text/css">
body {
padding-top: 10px;
padding-bottom: 40px;
}
</style>
</head>
<body>
<div class="container">
<script type="text/javascript">
function checkData() {
var q = document.getElementById("q").value.trim();
if (q == null || q == "") {
alert("請輸入您要查詢的關鍵字!");
return false;
} else {
return true;
}
}
</script>
<div class="row">
<div class="col-md-12" style="padding-top: 10px">
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">展開</span> <span class="icon-bar"></span> <span
class="icon-bar"></span> <span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="http://www.javaxl.com/index"><b
style="color: black"><strong>首頁</strong></b></a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse"
id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="http://122.114.92.43/p4/index" target="_blank"><b
color="black"><strong>美食</strong></b></a></li>
<li><a href="http://59.110.212.17/p5/index" target="_blank"><b
color="black"><strong>知識庫</strong></b></a></li>
<li><a href="http://www.javaxl.com/abortMe" target="_blank"><b
color="black"><strong>關於本站</strong></b></a></li>
</ul>
<form action="http://www.javaxl.com/admin/blog/q"
class="navbar-form navbar-right" role="search" method="post"
onsubmit="return checkData()">
<div class="form-group">
<input type="text" id="q" name="q" value="" class="form-control"
placeholder="請輸入要查詢的關鍵字...">
</div>
<button type="submit" class="btn btn-default">搜索</button>
</form>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid --> </nav>
</div>
</div>
<div class="row" style="margin-top: 50px;">
<!--
真正展示博客內容的地方,
所有博客鏈接的列表->list.jsp
單條博客詳情->view.jsp
呼和條件的博客詳情列表->result.jsp
-->
<div class="col-md-9">
<script type="text/javascript"
src="./freemarkerDemo_files/shCore.js.下載"></script>
<link rel="stylesheet"
href="./freemarkerDemo_files/shCoreDefault.css">
<script type="text/javascript">
/*本頁面用於查看博客鏈接中的詳細內容*/
SyntaxHighlighter.all();
function showOtherComment() {
$(".otherComment").show();
}
function loadimage() {
document.getElementById("randImage").src = "/static/system/jsp/common/image.jsp?"
+ Math.random();
}
function submitData() {
var content = $("#content").val();
var imageCode = $("#imageCode").val();
if (content == null || content == "") {
alert("請輸入評論內容!");
} else if (imageCode == null || imageCode == "") {
alert("請填寫驗證碼!");
} else {
$.post("/comment/save.do", {
"content" : content,
'imageCode' : imageCode,
'blog.bid' : '323'
}, function(result) {
if (result.success) {
window.location.reload();
alert("評論已提成成功,審覈通過後顯示!");
} else {
alert(result.errorInfo);
}
}, "json");
}
}
</script>
<div class="data_list">
<div class="data_list_title">
<img
src="./freemarkerDemo_files/blog_show_icon.png" />
博客信息
</div>
<div>
<div class="blog_title">
<h3>
<strong>${blog.title }</strong>
</h3>
</div>
<div class="blog_share">
<!-- <div class="bshare-custom"><a title="分享到QQ空間" class="bshare-qzone"></a><a title="分享到新浪微博" class="bshare-sinaminiblog"></a><a title="分享到人人網" class="bshare-renren"></a><a title="分享到騰訊微博" class="bshare-qqmb"></a><a title="分享到網易微博" class="bshare-neteasemb"></a><a title="更多平臺" class="bshare-more bshare-more-icon more-style-addthis"></a><span class="BSHARE_COUNT bshare-share-count">0</span></div><script type="text/javascript" charset="utf-8" src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=2&lang=zh"></script><script type="text/javascript" charset="utf-8" src="http://static.bshare.cn/b/bshareC0.js"></script> -->
</div>
<div class="blog_info">發佈時間:『${blog.releaseDate?datetime }』 博客類別:${blog.btid } 閱讀(${blog.clickHit })
</div>
<div class="blog_content">${blog.content }</div>
</div>
</div>
</div>
<!-- 右側佈局 -->
<div class="col-md-3">
<div class="data_list">
<div class="data_list_title">博主信息</div>
<div class="user_image">
<img src="./freemarkerDemo_files/index_1.jpg">
</div>
<div class="nickName">javaxl_小李飛刀</div>
<div class="userSign">(知識改變命運,教育改變生活)</div>
</div>
<div class="data_list">
<div class="data_list_title">
<img src="./freemarkerDemo_files/byType_icon.png"> 按日誌類別
</div>
<div class="datas">
<ul>
<li><span><a
href="http://www.javaxl.com/index.html?btid=9">java基礎(71)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=1">自定義mvc(8)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=2">前端框架(39)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=4">索引框架(7)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=5">SSH(14)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=6">SSM(9)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=7">服務器部署(5)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=8">項目異常歸總(5)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=10">安全框架(4)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=11">SpringBoot(15)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=12">程序人生(3)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=13">其他框架(5)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=14">開發工具(6)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=15">解決方案(7)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=16">23種設計模式(25)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=17">SpringCloud(14)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=18">第三方(4)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=19">Python(67)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?btid=20">底層探究(1)</a></span></li>
</ul>
</div>
</div>
<div class="data_list">
<div class="data_list_title">
<img src="./freemarkerDemo_files/byDate_icon.png"> 按日誌日期
</div>
<div class="datas">
<ul>
<li><span><a
href="http://www.javaxl.com/index.html?releaseDateStr=2019%E5%B9%B408%E6%9C%88">2019年08月(36)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?releaseDateStr=2019%E5%B9%B407%E6%9C%88">2019年07月(27)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?releaseDateStr=2019%E5%B9%B406%E6%9C%88">2019年06月(47)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?releaseDateStr=2019%E5%B9%B405%E6%9C%88">2019年05月(61)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?releaseDateStr=2019%E5%B9%B404%E6%9C%88">2019年04月(18)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?releaseDateStr=2019%E5%B9%B403%E6%9C%88">2019年03月(50)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?releaseDateStr=2019%E5%B9%B402%E6%9C%88">2019年02月(57)</a></span></li>
<li><span><a
href="http://www.javaxl.com/index.html?releaseDateStr=2019%E5%B9%B401%E6%9C%88">2019年01月(13)</a></span></li>
</ul>
</div>
</div>
<div class="data_list">
<div class="data_list_title">
<img src="./freemarkerDemo_files/link_icon.png"> 友情鏈接
</div>
<div class="datas">
<ul>
<li><span><a href="http://www.baidu.com/"
target="_blank">百度</a></span></li>
<li><span><a href="http://122.114.92.43/p4/index"
target="_blank">曉碼閣-美食網</a></span></li>
<li><span><a href="http://59.110.212.17/p5/index"
target="_blank">曉碼閣-知識庫</a></span></li>
</ul>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div align="center" style="padding: 20px">
<span style="float: left;">Powered by <a
href="http://www.javaxl.com/" target="_blank">博客首頁</a> V1.0
</span> Copyright © 2018-2019 javaxl曉碼閣 版權所有
</div>
</div>
</div>
</div>
</body>
</html>
Demo002
package com.javaxl.freemarker;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import com.javaxl.blog.util.DBAccess;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class Demo002 {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws IOException, TemplateException, SQLException {
// 1.創建配置類
Configuration configuration = new Configuration(Configuration.getVersion());
// 2.設置模板所在的目錄
configuration.setDirectoryForTemplateLoading(
new File("E:\\y2---study2\\javaxl_lunece_freemarker\\src\\main\\webapp\\freemarker"));
// 3.設置字符集
configuration.setDefaultEncoding("utf-8");
// 4.加載模板
Template template = configuration.getTemplate("blogDetail.ftl");
// 5.創建數據模型
// Map map = new HashMap();
// map.put("name", "小李飛刀 ");
// // 6.創建Writer對象
// Writer out = new FileWriter(new File("E:\\temp\\staticPage\\test.html"));
// // 7.輸出
// template.process(map, out);
// 8.關閉Writer對象
// out.close();
createPage(template);
}
private static void createPage(Template template) throws SQLException, IOException, TemplateException {
Connection con = DBAccess.getConnection();
String sql = "select * from t_lucene_freemarker_blog";
PreparedStatement pst = con.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
Map map = new HashMap<>();
Map<String, Object> blog = new HashMap<>();
while(rs.next()) {
blog.put("bid", rs.getObject("bid"));
blog.put("title", rs.getObject("title"));
blog.put("releaseDate", rs.getObject("releaseDate"));
blog.put("btid", rs.getObject("btid"));
blog.put("clickHit", rs.getObject("clickHit"));
blog.put("content", rs.getObject("content"));
map.put("blog", blog);
// // 6.創建Writer對象
Writer out = new FileWriter(new File("E:\\y2---study2\\javaxl_lunece_freemarker\\src\\main\\webapp\\freemarker\\"+blog.get("bid")+".html"));
// 7.輸出
template.process(map, out);
// 8.關閉Writer對象
out.close();
}
DBAccess.close(con, pst, rs);
}
}
效果圖:
使用頁面靜態化後的url