今天研究了一下項目中使用的裝飾器架構:sitemesh
首先來看一下百科的定義:SiteMesh 是一個網頁布局和修飾的架構,利用它可以將網頁的內容和頁面結構分離,以達到頁面結構共用的目的。OS(OpenSymphony)的SiteMesh是一個用來在JSP中實現頁面配置和裝飾(layout and decoration)的架構組件,能夠協助網站開發人員較容易實現頁面中動態內容和靜態裝飾外觀的分離。
sitemesh是通過servlet的fileter過濾器攔截response響應來實現的。SpringMVC中也是同樣的道理,通過SpringMVC封裝的過濾器,來實現對也頁面的過濾。
相同點:都能提高公用模組的複用性,提高開發效率。
不同點:include需要把需要用到的jsp檔案寫死到每一個jsp檔案中,而sitemesh則是動態,使用filter過濾response請求,然後把裝飾完成的頁面,返回給前端。
區別還是很大的,我們可以簡單的理解:sitemesh是動態,提供了更高的靈活性;而傳統的include方法是靜態,一旦需要改變公用部分,使用include是一件很麻煩的事情。
我們來看一個簡單的裝飾器:
首先要在web.xml中配置
<web-app> ... <filter> <filter-name>sitemesh</filter-name> <filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class> </filter> <filter-mapping> <filter-name>sitemesh</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
<span style="font-size:14px;"><body<decorator:getProperty property="body.id" writeEntireProperty="true"/><decorator:getProperty property="body.class" writeEntireProperty="true"/>> <!-- <div id="page"> --> <c:if test="${param.thirdFlag!='1'}"> <jsp:include page="/common/login-header.jsp"/> </c:if> <!-- </div> --> <!-- <div id="content" class="clearfix"> --> <!-- <div id="main"> --> <decorator:body/> <!-- </div> --> <!-- </div> --> <!-- <div id="footer" class="clearfix"> --> <c:if test="${param.thirdFlag!='1'}"> <jsp:include page="/common/footer.jsp"/> </c:if> <!-- </div> --> <!-- </div> --></body></span>
設定檔sitemesh.xml
<span style="font-size:14px;"><sitemesh> <property name="decorators-file" value="/WEB-INF/decorators.xml"/> <excludes file="${decorators-file}"/> <page-parsers> <parser default="true" class="com.opensymphony.module.sitemesh.parser.FastPageParser"/> <parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser"/> <parser content-type="text/html;charset=utf-8" class="com.opensymphony.module.sitemesh.parser.FastPageParser"/> </page-parsers> <decorator-mappers> <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"> <param name="config" value="${decorators-file}"/> </mapper> </decorator-mappers></sitemesh></span>
預設情況下,sitemesh只對HTTP回應標頭中的Content-type為text/html的類型進行攔截和裝飾,我們通常需要進行擴充,支援更多類型的Content-type
<mime-type>text/html</mime-type>
<mime-type>application/vnd.wap.xhtml+xml</mime-type>
<mime-type>application/xhtml+xml</mime-type>
設定檔 decorators.xml
<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?><decorators defaultdir="/decorators"> <excludes> <pattern>/index.html*</pattern> <pattern>/40*.jsp</pattern> </excludes> <decorator name="login-decorator" page="login-decorator.jsp"> <pattern>/signup.html</pattern> <pattern>/findpassword/*.html</pattern> </decorator> <decorator name="debitcard-decorator" page="debitcard-decorator.jsp"> <pattern>/debitcard/*.html</pattern> </decorator> <decorator name="helpcenter-decorator" page="helpcenter-decorator.jsp"> <pattern>/helpcenterinfo/*.html</pattern> </decorator><decorator name="item-decorator" page="mc-item-decorator.jsp"> <pattern>/productinfo/productItemDetail0.html*</pattern> <pattern>/productinfo/productItemDetail*.html*</pattern> </decorator> <decorator name="default" page="mc-decorator.jsp"> <pattern>/*</pattern> </decorator></decorators></span>
<!-- 預設裝飾器,當下面的路徑都不匹配時,啟用該裝飾器進行裝飾 -->
<mapping decorator="/default-decorator.html"/>
<!-- 對不同的路徑,啟用不同的裝飾器 -->
<mapping path="/admin/*" decorator="/another-decorator.html"/>
<mapping path="/*.special.jsp" decorator="/special-decorator.html"/>
<!-- 對同一路徑,啟用多個裝飾器 -->
<mapping>
<path>/articles/*</path>
<decorator>/decorators/article.html</decorator>
<decorator>/decorators/two-page-layout.html</decorator>
<decorator>/decorators/common.html</decorator>
</mapping>
<!-- 排除,不進行裝飾的路徑 -->
<mapping path="/javadoc/*" exclue="true"/>
<mapping path="/brochures/*" exclue="true"/>
<!-- 自訂 tag 規則 -->
<content-processor>
<tag-rule-bundle class="com.something.CssCompressingBundle" />
<tag-rule-bundle class="com.something.LinkRewritingBundle"/>
</content-processor>