1.爲什麼選用Tilesjavascript
剛接觸Java Web開發的人都知道,JSP中能夠經過include標籤動態插入一個JSP頁面。在瞭解這個功能後可能會興奮不已,由於這樣能夠實現多個JSP頁面共用一個JSP的內容。php
如今,假若有一個超級大的電子商務網站,網站擁有10萬個JSP頁面(悄悄告訴你,這僅僅是一個假設),而且每一個JSP都引用了同一個JSP(咱們稱這個JSP頁面爲A吧)。如今你就是這個網站的開發人員,有一天老闆跑到你面前說:「大量用戶反饋頁面A設計得太醜,嚴重影響用戶體驗,若是不在今天以內改進,他們就集體去競爭對手那裏購物,因此你今天必需要讓頁面A從網站上消失,不然炒魷魚走人」,這個凶神惡霸的老闆說完就甩手走出去了,你沒有任何辯解的機會。這時,恐怕你不會以爲本身一人可以搞定,那怎麼辦?程序員都有不少好基友,找一百個基友來一塊兒改,每人只須要改1000個頁面。否則,只有垂頭喪氣地收拾好東西離職了。前端
那麼,要是有一天老闆又跑過來找你,讓你爲每一個JSP頁面的底部加一個跳舞的小黃人,又該怎麼辦呢?先找前端工程師設計好跳舞的小黃人,而後用include標籤插入到10萬個JSP頁面。10萬個啊,又得請一百個好基友幫忙了!要是老闆後面又要在網站頂端加一隻唱歌的小鳥、在網站右邊加一個工具欄…估計你的好基友要用磚頭來砸你了。java
那有沒有一種方法,能夠不用請一百個好基友幫忙,就能夠在十分鐘以內完成老闆交給你的任務?也許你會以爲這簡直是胡說八道,在十分鐘內改完10萬個JSP頁面就是一種瘋狂的想法。也許這是對的,就是一個瘋狂的想法,不清楚Tiles的設計者當初也是否受到過這種老闆的虐待,因此才設計出了這樣一個瘋狂的產品—— Tiles 。程序員
沒錯,Tiles就是爲你遇到的這種需求服務的。一旦你在網站系統中使用了Tiles技術,若老闆讓你刪除10萬個頁面所引用的一個JSP,若是你的速度快的話,你能夠在10秒鐘以內解決。那要想再讓這10萬個頁面去引用一個JSP呢?也是同樣的操做,很是簡單。web
2. 初相識spring
本文所講的示例使用Spring MVC框架(也可使用Struts,使用方法和本文相似),爲工程添加Tiles特性很容易,如果Maven項目,直接在pom.xml中添加如下依賴便可:express
<dependency> <groupId>org.apache.tiles</groupId> <artifactId>tiles-extras</artifactId> <version>3.0.5</version> </dependency>
若不是Maven項目怎麼辦?能夠直接到Apache的 Tiles 項目頁面下載jar包就能夠了。
接下來,咱們就要開始Tiles旅程了,你準備好了嗎?
新建一個佈局文件,命名爲layout.xml,咱們要在這個文件裏配置網站的佈局,內容以下: apache
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd"> <tiles-definitions> <!-- 主佈局 --> <definition name="layout" template="/mainLayout.jsp"> </definition> <!-- 主佈局 --> <!-- 項目 --> <definition name="myView" extends="layout"> <put-attribute name="a" value="/a.jsp" /> <put-attribute name="b" value="/b.jsp" /> </definition> <!--項目--> </tiles-definitions>
其中,mainLayout.jsp就是咱們的主佈局模板,它決定整個網頁須要顯示的內容以及顯示到什麼地方。而a.jsp和b.jsp就是模板裏須要顯示的兩個引用頁面。簡而言之,mainLayout.jsp這個頁面引用了a.jsp和b.jsp兩個頁面。mainLayout.jsp頁面的內容以下: 後端
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> <%@ taglib uri="http://tiles.apache.org/tags-tiles-extras" prefix="tilesx" %> <div> <tiles:insertAttribute name="a" /> <tiles:insertAttribute name="b" /> </div>
a表示在這裏插入的a.jsp,b表示將要在這裏插入的b.jsp。a.jsp和b.jsp中的內容就隨意了,這裏咱們在a.jsp的內容是」我是a.jsp「,b.jsp 的內容是 」我是b.jsp「,具體的代碼就不貼了。
而後,咱們須要爲Tiles配置視圖解析器,在springMVC-servlet.xml(MVC的配置文件,不懂的先百度查詢一下)中添加如下內容:
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver" p:order="1"/> <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer"> <property name="definitions"> <list> <value>classpath:layout.xml</value> </list> </property> </bean>
其中的layout.xml即爲前文所創建的佈局配置文件,p:order="1"表示優先級,數字越小,解析器的優先級越高。
如今,咱們就要爲視圖編寫控制器了,咱們寫一個控制器命名爲TestController.java,主要代碼以下:
@RequestMapping("/test") public String testView() { return 「myView」; //這裏的myView爲layout.xml中配置的視圖名稱 }
運行Web程序,輸入xxx/test(xxx爲url前綴)能夠看到「我是a.jsp 「和」我是a.jsp 「顯示出來。
也許你開始納悶了,忙活了這麼久,沒有發現能夠利用Tiles在十秒內解決老闆交代的任務啊!別急,好戲還在後面!
3. 進入主題
剛纔咱們經過訪問 xxx/test ,就訪問到了引入了a.jsp和b.jsp主佈局頁面,那麼Tiles是怎麼作到的呢?當Spring MVC的DispatchServlet收到來自瀏覽器的請求後,分析出須要請求的控制器,而後訪問解析出來的控制器TestController的testView方法,接着就開始解析視圖了。由於咱們用的是Tiles的視圖解析器,激情飽滿的二級制代碼就訪問到了layout.xml,最後根據layout.xml的配置組裝成咱們看到的頁面。那如何解決大量頁面引用同一個頁面的問題呢?
若是隻能爲每個項目頁面在layout.xml中創建一個definition塊,那麼Tiles都沒有完美地解決問題,若是你想避免被老闆炒魷魚,在建立頁面的時候,須要爲10萬個頁面各自創建一個definition塊,並引入公共的頁面A,當老闆不喜歡這個頁面A的時候,你須要在這10萬個definition塊中刪除A,這樣的工做量仍是很大的。因此, Tiles展示威力的時候到了。
咱們改寫layout.xml,使之適應你的網站。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd"> <tiles-definitions> <!-- 主佈局 --> <definition name="layout" template="/mainLayout.jsp"> </definition> <!-- 主佈局 --> <!-- 項目 --> <definition name="myView" extends="layout"> <put-attribute name="A" value="/A.jsp" /> <put-attribute name="item" expression="/${item}.jsp" /> </definition> <!--項目--> </tiles-definitions>
這裏的A.jsp就是你老闆深惡痛絕的頁面,而${item}.jsp就表明着大家網站的10萬個項目頁面(這裏用到了EL表達式,若是有不懂的,能夠先百度瞭解一下)。
再修改mainLayout.jsp頁面:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> <%@ taglib uri="http://tiles.apache.org/tags-tiles-extras" prefix="tilesx" %> <div> <tiles:insertAttribute name="A" /> <tiles:insertAttribute name="item" /> </div>
A表示A.jsp中的內容,而item就表明那10萬個項目頁面。
繼續修改TestController.java,將testView改成introductionView:
public String introductionView(Model model) {
model.addAttribute("item","introduction"); return 「myView」; //這裏的myView爲layout.xml中配置的視圖名稱 }
這裏假設introduction.jsp爲公司介紹頁面,當訪問introductionView時,layout.xml中${item}.jsp就能匹配到introduction.jsp。那麼,若是還有一個兔子頁面rabbit.jsp,那麼經過訪問rabbitView就能訪問到兔子頁面…如今,若是你把10萬個頁面都這樣設計,老闆讓你刪除A頁面,知道如何刪除嗎?告訴你,直接把layout.xml的myView中的A屬性刪除就能夠了,10秒鐘是否是太多了?是的,Titles就這麼神奇。 4. Tiles讓動態模板變得更加容易 經過前文所述,能夠看出Tiles很擅長處理後端動態模板的。那麼問題又來了,如今也有不少技術適合作前端模板,好比ejs。ejs的工做方式是在js代碼中動態選擇ejs模板。如今簡要分析一下ejs的工做流程,在js代碼中肯定模板之後,由js從後臺拉取對應的ejs文件,而後將預先獲得的數據填充到ejs模板中,最後才展示給終端用戶。從處理速度上分析,Tiles的處理速度通常比js要快。從請求次數而言,使用Tiles時,終端用戶只須要請求一次,若使用ejs,則須要請求兩次。從可維護性而言,明顯Tiles項目的維護性強於ejs。所以,你儘管大膽地在項目中使用Tiles,它可讓你的產品性能表現得更出色。Tiles還有更多強大的功能,若是你感興趣,能夠去Tiles項目主頁瞭解更多內容。