SiteMesh通过Decorator的设计模式,十分利索地达到了目的。其设计思想是,用户发送request至服务器,服务器根据此request生成动态数据,生成网页,准备返回给客户端。就在返回前,SiteMesh进行拦截,对此网页进行解析,将title、body等部分拆解出来,套上模板后,再返回给客户端。由于SiteMesh在返回客户端的最后一步工作,此时的网页已经具备了标准的html网页格式,因此SiteMesh只需解析标准的html网页,无需考虑各个Web应用是应用了JSP、ASP,还是Velocity技术,相当灵活。
一般情况下,我们在decorators.xml文件中定义一个模板main.jsp,来自动套用未加装饰的网页:
<?xml version="1.0" encoding="GBK"?> <decorators defaultdir="/decorators"> <!-- 在excludes元素下指定的页面将不会由SiteMesh来装饰 --> <excludes> <pattern>/login.jsp*</pattern> </excludes> <!-- 创建一个名为main的装饰器,该装饰器页面为main.jsp, 用于装饰pattern指定的URL的所有页面--> <decorator name="main" page="main.jsp"> <pattern>/*</pattern> </decorator> <!-- 定义一个装饰器,但该装饰器默认不装饰任何页面 ,不需要<pattern>参数 --> <decorator name="panel" page="panel.jsp"/> </decorators>
示例:
主包装器页面:decorators/main.jsp
特定包装器页面:decorators/panel.jsp
被装饰页面:tiny-panel.jsp
在main.jsp页面中:
在main.jsp这中<page:param/>参数申明的值参数被panel.jsp页面中的<decorator:getProperty/>标签访问。<c:out value="使用<page:apply-decorator/>:"></c:out> <page:apply-decorator page="/tiny-panel.jsp" name="panel"> <page:param name="email">xxx.net</page:param> </page:apply-decorator> <c:out value="使用<page:applyDecorator/>:"></c:out> <page:applyDecorator page="/tiny-panel.jsp" name="panel"> <page:param name="email"> <a href="mailto:<decorator:getProperty property="meta.author" default="xxf@gmail.com"/>">@gmail.com</a> </page:param> </page:applyDecorator>
在panel.jsp页面中
<table width=250 border=0 cellpadding=0 cellspacing=0> <tr> <th class="panelTitle"> <decorator:title default="Unknown panel"></decorator:title> </th> </tr> <tr> <th class="panelBody"> <decorator:body/> <decorator:getProperty property="email"></decorator:getProperty> </th> </tr> </table>
运行效果:见图
将tiny-panel.jsp会被默认的包装页面main.jsp包装上header,footer外,main.jsp页面中还内嵌了tiny-panel.jsp页面,并且此tiny-panel.jsp页面还会被panel.jsp包装为一个title加body的有2段的页面,第1段是tiny-panel.jsp的title,第2段是tiny-panel.jsp的body内容。
引用另外一篇文章:
http://read.newbooks.com.cn/info/196576.html
当SiteMesh工作时,它会分解出title及body的内容,并将其分别通过<decorator:title>及<decorator:body>套用到默认的main.jsp上。
页面需要不同的装饰器,就在相应的jsp页面的title行加上:
<meta name="decorator" content="download_decorator" /> //SiteMesh将根据此元数据的指示,自动调用download_decorator.jsp的装饰器。
配合使用SiteMesh的另一个标签<decorator:usePage>,我们可以顺利地为page属性设定值。
<decorator:usePage id="myPage" />
<page:applyDecorator page='<%= myPage.getProperty("meta.sidebar") %>' name="sidebar" />
<decorator>就是一个setter,而<page:applyDecorator>则是一个getter,因此它必须自己去寻找所需的素材。如果我们能根据依赖注入模式,为其注入所需素材,那么,就像<decorator>一样,它也不需要再变了。