打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
SiteMesh3原理和SpringMVC + FreeMarker + SiteMesh3问题

先附上一个SiteMesh3+FreeMarker+SpringMVC例子http://files.cnblogs.com/adaikiss/sitemesh3_freemarker_springmvc.zip

下载后解压,本地环境变量要有MAVEN,CMD进入工程目录直接运行mvn jetty:run

 

昨天花了一天时间来跟踪调试springmvc, freemarker, sitemesh3, 终于弄明白了大概的原理,最后解决了sitemesh中文(UTF-8)乱码,ftl装饰页不被渲染的问题。

sitemesh3是通过一个filter来对response进行拦截处理,在response提交之前,它会把response流里的数据备份起来,清空流,然后用request.getRequestDispatcher(装饰页URI).forward()来取得渲染后的装饰页,然后再把装饰页里的标签替换成之前备份的对应内容。

也就是说sitemesh不关心你的页面是如何生成的,它只是将两者拼接起来,不管你用的是JSP,Volocity, FreeMarker 还是 SpringMVC, Struts, wicket。

这样一来你就可以灵活地控制页面的生成方式。你可以把sitemesh3当成一个中间浏览器,他使用用户浏览器发送过来的request对象发送了两次(或以上)请求,第一次是原来的请求, 第二次是对装饰页面的请求,然后把这两个请求结果拼接起来返回给用户浏览器。

看到这里,装饰页如果是FTL就不被渲染的问题也就有了解决方法了。只要自己写一个过滤器对.ftl的请求用freemarker渲染一遍就可以了。由于我使用的是springmvc + freemarker,因此我直接拿springmvc来渲染FTL文件了,这样可以像被装饰页一样方便地使用spring的宏和其他一些对象。下面是我的filter

public class FreemarkerFilter implements Filter {    private Locale locale;    @Override    public void init(FilterConfig filterConfig) throws ServletException {        String localeStr = filterConfig.getInitParameter("locale");        if(StringUtils.isNotBlank(localeStr)){            locale = new Locale(localeStr);        }else {            locale = Locale.getDefault();        }    }    @Override    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain chain) throws IOException, ServletException {        try {            HttpServletRequest req = (HttpServletRequest)request;            HttpServletResponse res = (HttpServletResponse)response;            String name = req.getRequestURI();            name = name.substring(1, name.lastIndexOf(".ftl"));            FreeMarkerViewResolver viewResolver = SpringContextHolder.getBean(FreeMarkerViewResolver.class);            View view = viewResolver.resolveViewName(name, locale);            @SuppressWarnings("unchecked")            Map<String, Object> model = (Map<String, Object>) request.getAttribute(ViewRendererServlet.MODEL_ATTRIBUTE);            view.render(null, req, res);        } catch (Exception e) {            throw new ServletException(e);        }    }    @Override    public void destroy() {        // TODO Auto-generated method stub            }    }

在这里,我是把SpringMVC对被装饰页处理时生成的model传到了装饰页。装饰页和原来被include进来的页面差不多,一般装饰页可能不需要使用被装饰页中的model, 可以把SuppressWarnings注解下面那行注释掉,下面传null过去。

在web.xml里加上过滤器配置:

<filter>      <filter-name>freemarkerFilter</filter-name>      <filter-class>org.adaikiss.kay.web.FreemarkerFilter</filter-class>  </filter>  <filter-mapping>      <filter-name>freemarkerFilter</filter-name>      <url-pattern>*.ftl</url-pattern>      <dispatcher>REQUEST</dispatcher>    <dispatcher>FORWARD</dispatcher>  </filter-mapping>

 

这样一来由sitemesh forward的请求就能被拦截并渲染。当然,你也可以把装饰页的后缀改成.des,url-pattern要同步改。

 

关于中文乱码的问题,在跟踪代码的时候发现对于没有contentType的view,SpringMVC会使用默认的contentType:AbstractTemplateView.DEFAULT_CONTENT_TYPE,即

"text/html;charset=ISO-8859-1",view 中可以设置这个属性,不过我的配置里没有定义view,还好ViewResolver里也可以设置,在springmvc配置文件里加上contentType属性即可。

<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="contentType" value="text/html; charset=UTF-8"/>

...

</bean>

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【转】SiteMesh 2学习:装饰文件decorators.xml说明
FreeMarket模板引擎快速入门【面试+工作】
sitemesh性能测试结果比较惊艳(已经补上新的对比测试结果)
SiteMesh:一个优于Apache Tiles的Web页面布局、装饰框架 - yjhm...
使用SiteMesh简化网页布局
freemarker(FTL)常见语法(JSP中的代码转化为ftl代码) 备忘录
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服