典型 Web 分層:前端 (JSP/Velocity) → 控制層 → 業務層 → 持久層。前端頁面邏輯難以複用,Sitemesh 透過 Filter 在輸出端統一裝飾,達成解耦。
除 sitemesh.jar、兩個 .tld 外,WEB-INF 可選放置:
sitemesh.xml:配置 Page Parsers 與 Decorator Mappers(通常用預設值即可)。decorators.xml:核心映射配置。<sitemesh>
<page-parsers>
<parser class="com.opensymphony.module.sitemesh.parser.DefaultPageParser" default="true"/>
<parser class="com.opensymphony.module.sitemesh.parser.FastPageParser" content-type="text/html"/>
</page-parsers>
<decorator-mappers>
<mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"/>
<mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"/>
</decorator-mappers>
</sitemesh>
PrintableDecoratorMapper 支援 ?printable=true 參數輸出無裝飾原始頁面,方便列印。
<decorators defaultdir="/_decorators">
<decorator name="main" page="main.jsp">
<pattern>*</pattern>
</decorator>
<decorator role="customer" name="printable" page="printable.jsp" webapp="otherApp">
<pattern>/reports/*</pattern>
</decorator>
</decorators>
defaultdir:裝飾器頁面根目錄role:角色型安全控制webapp:跨應用引用裝飾器pattern:URL 匹配模式 (Ant 風格)| 標籤 | 說明 |
|---|---|
<decorator:head> | 插入原始頁面 <head> 內部內容 |
<decorator:body> | 插入原始頁面 <body> 內部內容 |
<decorator:title default="..."> | 插入 <title> 文字,可設預設值 |
<decorator:getProperty property="..." [writeEntireProperty="true"]> | 取得原始頁面任一標籤屬性值 |
<decorator:usePage id="page"> | 將原始頁面暴露為 Page 物件,可用 ${page.title} 等 |
<page:applyDecorator>在內容頁面主動指定裝飾器,實現區塊級嵌套裝飾。
裝飾器 _decorators/panel.jsp:
<%@ taglib uri="sitemesh-decorator" prefix="decorator" %>
<div class="panel">
<h3><decorator:title/></h3>
<div class="body"><decorator:body/></div>
</div>
被嵌入頁面 _public/date.jsp:
<%= new java.util.Date() %>
主內容頁 page.jsp:
<%@ taglib uri="sitemesh-page" prefix="page" %>
...
<page:applyDecorator name="panel" page="/_public/date.jsp">
<page:param name="myEmail" value="chen_p@neusoft.com"/>
</page:applyDecorator>
結果:page.jsp 先被全域裝飾器包裝,內部 date.jsp 又被 panel.jsp 二次裝飾,並可在 panel.jsp 中透過 <decorator:getProperty property="myEmail"/> 取得參數。
ConfigDecoratorMapper + decorators.xml 統一管理。PrintableDecoratorMapper 提供列印友善版本。