1.背景:
最近在搭建自己的springmvc+sitemesh2+freemarker框架时,遇到了一个问题,就是sitemesh2整合springmvc时,springmvc没有正确的渲染sitemesh2的模板页面,在一番百度之后,发现网上类似问题有不少人遇到,但是没有一个明确的解决方案。现在记录下我自己的解决方案,供大家参考。
2.问题原因分析:
解决问题要对症下药,首先就是确定问题原因。那么为什么springmvc没有渲染sitemesh2的模板页呢?首先需要了解一下sitemesh和springmvc的工作原理。
2.1 sitemesh工作原理:
这个百度一下,随处可见。这里做简要的说明。sitemesh2的工作步骤大致如下:
a.拦截请求判断该请求目标是否需要加载其他模板;
b.不需要,则直接放行;需要则先获取请求目标的输出流,在web项目中表现为目标html页面的输出流。
c.在需要加载其他模板页的情况下,将请求目标页面的输出流保存在request中,之后做站内转发
,获取模板页的内容(如果有多个模板页则重复这一过程)
d.在获取请求目标和所有需要的模板页之后,将他们整合成一个页面
2.2 springmvc渲染页面过程:
springmvc的servlet在拦截的请求之后,会调用对应的handler来处理请求,之后再使用springmvc内置的freemarker渲染工具类将handler中加载的数据渲染到页面上。如果没有对应的handler,那么springmvc只好直接返回请求的目标页面。
2.3 原因分析:
简要了解了sitemesh和springmvc的工作过程之后,问题的原因就能说明白了。sitemesh在进行站内转发获取模板页面时,发送的目标请求地址就是我们在sitemesh配置文件中的模板页的位置,,当spring mvc拦截到这个站内的这个转发请求,显然这个请求是没有对应的handler来处理的,接着springmvc就放弃了对这个页面进行渲染,继而sitemesh接受到的模板页也就是没有经过渲染的。
3.解决方案:
3.1 解决方案思路:
通过分析,我们知道是springmvc因为没有对应的handler来处理sitemesh转发的请求,因此没有渲染模板页,那我们就自己渲染。通过什么样的方式来渲染呢?根据sitemesh的特性,我们可以写一个filer,来专门拦截sitemesh转发过来的请求,然后主动调用springmvc的渲染方法来渲染模板页。