今天研究了一下项目中使用的装饰器框架: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>
<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>
<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>