SiteMesh3整合SpringMVC+FreeMarker
SiteMesh3文档 http://wiki.sitemesh.org/wiki/pages/viewpage.action?pageId=1081348
重新搭建项目偶然发现SiteMesh有了新版本SiteMesh3,本着用新不用旧原则果断升级,多少遇了点坑,顺便记录下

SiteMesh3配置
添加maven依赖
<dependency>
<groupId>org.sitemesh</groupId>
<artifactId>sitemesh</artifactId>
<version>3.0.1</version>
</dependency>添加filter
在web.xml中添加filter
<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>配置servlet
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>添加sitemesh配置文件
添加配置文件 sitemesh3.xml
默认配置文件路径为:/WEB-INF/sitemesh3.xmlsitemesh3.xml<sitemesh>
<!--
By default, SiteMesh will only intercept responses that set the Content-Type HTTP header to text/html
This can be altered to allow SiteMesh to intercept responses for other types.
默认 SiteMesh 只对HTTP响应头中Content-Type为 text/html 的类型进行拦截和装饰,若需要处理其它mime类型需要自行添加配置
-->
<mime-type>text/html</mime-type>
<!--
Map default decorator. This shall be applied to all paths if no other paths match.
配置装饰器,仅设置decorator参数时表示为默认的装饰器,当没有任何路径被匹配时会使用默认装饰器装配
-->
<mapping decorator="/WEB-INF/decorators/decorator.ftl"/>
<!--对不同的路径指定特定的装饰器-->
<!--<mapping path="/admin/*" decorator="/WEB-INF/decorators/admin-decorator.ftl"/>-->
<!--
Alternative convention. This is more verbose but allows multiple decorators to be applied to a single path.
对同一路径可以同时使用多个装饰器
-->
<mapping>
<path>/category/*</path>
<decorator>/WEB-INF/decorators/common-decorator.ftl</decorator>
<decorator>/WEB-INF/decorators/menu-decorator.ftl</decorator>
<decorator>/WEB-INF/decorators/category-decorator.ftl</decorator>
</mapping>
<!--
Exclude path from decoration.
排除路径,只需将exclue设置为true即可
-->
<mapping path="/static/*" exclue="true"/>
<!--
An advanced feature of SiteMesh is the ability to define custom rules that manipulate tags on a page.
These are classes that implement org.sitemesh.content.tagrules.TagRuleBundle.
默认SiteMesh仅支持title、head、meta、body等tag,可以自定义tag,实现TagRuleBundle接口即可
-->
<content-processor>
<tag-rule-bundle class="com.sankuai.shangchao.util.HtmlTagRuleBundle"/>
</content-processor>
</sitemesh>修改配置文件路径
默认配置文件路径为:/WEB-INF/sitemesh3.xml 若需要修改配置文件路径需要在filter里配置configFile参数<filter>
<filter-name>sitemesh</filter-name>
<filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class>
<init-param>
<param-name>configFile</param-name>
<param-value>/WEB-INF/sitemesh3.xml</param-value>
</init-param>
</filter>自定义tag
HtmlTagRuleBundle.javaimport 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; /**
* Description: FootTagRuleBundle
* Author: liuzhao
* Create: 2015-08-22 09:21
*/
public class HtmlTagRuleBundle implements TagRuleBundle {
@Override
public void install(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {
defaultState.addRule("foot", new ExportTagToContentRule(siteMeshContext, contentProperty.getChild("foot"), false));
} @Override
public void cleanUp(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) { }
}
decorator示例
decorator配置页面布局layout,对应的tag会被进行装饰替换
decorator.ftl<!DOCTYPE html><html><head><title><sitemesh:writeproperty="title"/></title><sitemesh:writeproperty='head'/></head><body><h1>啦拉拉,我是卖报的小行家</h1><sitemesh:writeproperty='body'/><sitemesh:writeproperty="foot"/></body></html>SpringMVC、FreeMarker配置(404问题处理)
sitemesh3是完全独立的,不和任何框架进行偶合,因此SpringMVC、FreeMarker配置完全不需要考虑sitemesh3的兼容问题
在加载装饰器的时候,会出现404问题,可能的原因是找不到ftl文件的解析器,所以需要配置下ftl使用默认的Servlet解析,在web.xml中添加如下配置<servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.ftl</url-pattern></servlet-mapping>

decorate源码
@OverrideprotectedbooleanpostProcess(String contentType, CharBuffer buffer,HttpServletRequest request, HttpServletResponse response,ResponseMetaData metaData)throwsIOException, ServletException {WebAppContext context = createContext(contentType, request, response, metaData);Content content = contentProcessor.build(buffer, context);if(content ==null) {returnfalse;}String[] decoratorPaths = decoratorSelector.selectDecoratorPaths(content, context);//遍历装饰器进行装饰for(String decoratorPath : decoratorPaths) {content = context.decorate(decoratorPath, content);}if(content ==null) {returnfalse;}try{content.getData().writeValueTo(response.getWriter());}catch(IllegalStateException ise) {// If getOutputStream() has already been calledcontent.getData().writeValueTo(newPrintStream(response.getOutputStream()));}returntrue;}publicContent decorate(String decoratorName, Content content)throwsIOException {if(decoratorName ==null) {returnnull;}classCharBufferWriterextendsCharArrayWriter {publicCharBuffer toCharBuffer() {returnCharBuffer.wrap(this.buf,0,this.count);}}CharBufferWriter out =newCharBufferWriter();decorate(decoratorName, content, out);CharBuffer decorated = out.toCharBuffer();Content lastContent = currentContent;currentContent = content;try{returncontentProcessor.build(decorated,this);}finally{currentContent = lastContent;}}@Overrideprotectedvoiddecorate(String decoratorPath, Content content, Writer out)throwsIOException {HttpServletRequest filterableRequest =newHttpServletRequestFilterable(request);// Wrap response so output gets buffered.HttpServletResponseBuffer responseBuffer =newHttpServletResponseBuffer(response, metaData,newBasicSelector(newPathMapper<Boolean>(), includeErrorPages) {@OverridepublicbooleanshouldBufferForContentType(String contentType, String mimeType, String encoding) {returntrue;// We know we should buffer.}});responseBuffer.setContentType(response.getContentType());// Trigger buffering.// It's possible that this is reentrant, so we need to take a copy// of additional request attributes so we can restore them afterwards.Object oldContent = request.getAttribute(CONTENT_KEY);Object oldContext = request.getAttribute(CONTEXT_KEY);request.setAttribute(CONTENT_KEY, content);request.setAttribute(CONTEXT_KEY,this);try{// Main dispatch.dispatch(filterableRequest, responseBuffer, decoratorPath);// Write out the buffered output.CharBuffer buffer = responseBuffer.getBuffer();out.append(buffer);}catch(ServletException e) {//noinspection ThrowableInstanceNeverThrownthrow(IOException)newIOException("Could not dispatch to decorator").initCause(e);}finally{// Restore previous state.request.setAttribute(CONTENT_KEY, oldContent);request.setAttribute(CONTEXT_KEY, oldContext);}}protectedvoiddispatch(HttpServletRequest request, HttpServletResponse response, String path)throwsServletException, IOException {//这里调用加载文件会出现404错误 /WEB-INF/decorators/decorator.ftlRequestDispatcher dispatcher = servletContext.getRequestDispatcher(path);if(dispatcher ==null) {thrownewServletException("Not found: "+ path);}dispatcher.forward(request, response);}
SiteMesh3整合SpringMVC+FreeMarker的更多相关文章
- sonne_game网站开发03 spring-mvc+freemarker整合
今天的任务就是在spring+mybatis+springmvc的基础上,将freemarker整合进来. freemarker是什么? freemarker是一种模板引擎.它的目的是基于模板和数据, ...
- spring-mvc+freemarker整合(sonne_game网站开发03)
今天的任务就是在spring+mybatis+springmvc的基础上,将freemarker整合进来. freemarker是什么? freemarker是一种模板引擎.它的目的是基于模板和数据, ...
- SpringBoot整合系列-整合SpringMVC
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9984607.html SpringBoot整合Spring MVC 步骤 第一步:添加必 ...
- freemarker学习 (servlet + freemarker -> Struts2+freemarker -> springMVC+freemarker)
什么是freemarker? freemarker类似于jsp,但不是jsp!怎么说呢?freemarker文件后缀是.ftl,它不像jsp本质是servlet,它将构建模板.解析模板.使用模板分离开 ...
- CXF WebService整合SpringMVC的maven项目
首先推荐博客:http://www.cnblogs.com/xdp-gacl/p/4259481.html http://blog.csdn.net/hu_shengyang/article/de ...
- SpringMVC+Freemarker+JSTL支持
前提: 网页编程中,我的思路是,通用的模块不仅仅只有后台代码,前端页面也可以独立为模块. 这个和asp.net中的UserController很像 比如有个人员基本信息的展示界面,需要在多个界面中嵌入 ...
- springMVC+freemarker中Could not resolve view with name... 问题解决
用到springMVC+freemarker,自己在做demo过程中报: 严重: Servlet.service() for servlet springmvc threw exception jav ...
- spring整合springmvc和hibernate
上篇文章使用maven搭建了web环境,这篇来记录下如何使用spring整合springmvc和hibernate,亦即spring+springmvc+hibernate框架整合. 第一步:首先配置 ...
- springmvc 项目完整示例07 设置配置整合springmvc springmvc所需jar包springmvc web.xml文件配置
前面主要是后台代码,spring以及mybatis的整合 下面主要是springmvc用来处理请求转发,展现层的处理 之前所有做到的,完成了后台,业务层和持久层的开发完成了 接下来就是展现层了 有很多 ...
随机推荐
- DB2死锁的解决办法
db2 get snapshot for locks on sampledb2 get db cfg for sampledb2 update db cfg using dlchktime 10000 ...
- app.js
//第一步,引入express模块 var exp = require('express'), http = require('http'),//引入http模块 path = req ...
- ubuntu下python 2.7与python 3.X的转换
ubuntu下python 2.7与python 3.X的转换 由于ubuntu本身自带python 2.7,而python 3.X与2.7有很多不同,所以在使用python 3.X时会带来诸多不便. ...
- 小试牛刀--利用豆瓣API爬取豆瓣电影top250
最近得赶进度爬点东西,对于豆瓣,它为开发者提供了API,目前是v2版本,目前key不对个人开放,但是可以正常通过其提供的API获取数据.豆瓣V2版API权限分3类:公开.高级.商务,我们用开放基本数据 ...
- .net配置文件读取
public static string LogPath { get { return AppSettingValue(); } } public static string AppSettingVa ...
- Red Hat Enterprise Server 5.8+oracle10g(中文界面)安装
Red Hat Enterprise Server 5.8+oracle10g(中文界面)安装 VMware workstation10(虚拟机)下面安装红帽企业版5.8 创建虚拟机 新建虚拟机,选择 ...
- 猿团YTFCloud--5分钟自制APP,开发从未如此简单
9月15日,YTFCloud将正式开启内测, 这意味着猿团YTF框架产品线全面升级.同时,公测过后,YTFCloud的APP线上DIY服务将面向所有用户,让人人都能成为APP“开发商”. 什么是YTF ...
- 【fortify】安全漏洞的分类
https://vulncat.hpefod.com/zh-cn 下面摘要著名的软件安全专家Gary Mc Graw的2006年的新书<Software Security building se ...
- mysql无法登录
很久没用root账户登录mysql发现无法登录 以为root密码被修改 修改root密码后还是无法登录 判断ip没权限 运行 Grant all privileges on *.* to 'root' ...
- SpringMVC常用注解實例詳解2:@ModelAttribute
我的開發環境框架: springmvc+spring+freemarker開發工具: springsource-tool-suite-2.9.0JDK版本: 1.6.0_29tomcat ...