0. 原理
SiteMesh是基于Servlet的filter的,即过滤流。它是通过截取response,并进行装饰后再交付给客户。
1. 添加sitemesh依赖
<dependency>
<groupId>org.sitemesh</groupId>
<artifactId>sitemesh</artifactId>
<version>3.0.1</version>
</dependency>
2. 创建过滤器Sitemesh3Filter
.java
package com.fukaiit.filter;
import javax.servlet.annotation.WebFilter;
import org.sitemesh.builder.SiteMeshFilterBuilder;
import org.sitemesh.config.ConfigurableSiteMeshFilter;
import org.springframework.context.annotation.Configuration;
import com.fukaiit.tagrule.CustomTagRuleBundle;
@Configuration
@WebFilter(filterName="Sitemesh3Filter",urlPatterns="/*")
public class Sitemesh3Filter extends ConfigurableSiteMeshFilter {
@Override
protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
builder.addDecoratorPath("/*", "/decorator/default")
.addExcludedPath("/static/**")//白名单,静态资源
.addTagRuleBundle(new CustomTagRuleBundle());
}
}
- 如需通过xml方式配置sitemesh过滤器,请参考这里。
- 测试必须添加@Configuration注解才能成功装饰,但在别人的项目中看到并未添加@Configuration注解也能装饰,具体未懂,后续补充。
3. 添加自定义规则CustomTagRuleBundle
.java
package com.fukaiit.tagrule;
import org.sitemesh.SiteMeshContext;
import org.sitemesh.content.ContentProperty;
import org.sitemesh.content.tagrules.TagRuleBundle;
import org.sitemesh.content.tagrules.html.ExportTagToContentRule;
import org.sitemesh.tagprocessor.State;
public class CustomTagRuleBundle implements TagRuleBundle{
@Override
public void install(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {
defaultState.addRule("myScript", new ExportTagToContentRule(siteMeshContext,
contentProperty.getChild("myScript"), false));
defaultState.addRule("myContent", new ExportTagToContentRule(siteMeshContext,
contentProperty.getChild("myContent"), false));
defaultState.addRule("myStyle", new ExportTagToContentRule(siteMeshContext,
contentProperty.getChild("myStyle"), false));
}
@Override
public void cleanUp(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {
}
}
4. 添加DecoratorController
.java
package com.fukaiit.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/decorator")
public class DecoratorController {
@RequestMapping("/default")
public String defaultDecorator(){
return "decorator/default";
}
}
5. 在templates/decorator下创建装饰页面default.html
在装饰页面中添加类似如下标签,嵌入"被装饰页面"中对应标签中的内容:
<sitemesh:write property='title'/>
<sitemesh:write property='head'/>
<sitemesh:write property='body'/>
<!-- 以下为自定义标签 -->
<sitemesh:write property="myStyle" />
<sitemesh:write property="myContent" />
<sitemesh:write property="myScript" />
标签
<sitemesh:write property='...'/>
将会被SiteMesh重写,用来包含从“被装饰页面”(content page)中提取到的值。
6. 创建被装饰页面
在被装饰页面中用自定义标签包裹要嵌入装饰页面中的内容:
<myStyle></myStyle>
<myContent></myContent>
<myScript></myScript>