1.关于layoutUrl路径的问题

一个layoutUrl的属性配置:<property name="layoutUrl" value="layout/layout.vm" />, 
这个配置是设置你的layout文件的存在路径,需要注意的是,这个路径不是相对于webapp路径来的,
而是相对于velocityConfig配置中的resourceLoaderPath属性配置的路径
(resourceLoaderPath的路径是相对于webapp的路径)
 <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/views/"/>
        <property name="configLocation" value="classpath:velocity.properties"/>
    </bean>

    <!-- 配置视图的显示 -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
        <!-- 如果配置了toolbox.xml则在velocity模板中可直接使用java后台代码了 -->
        <property name="toolboxConfigLocation" value="/WEB-INF/classes/toolbox.xml" />
        <property name="suffix" value=".vm" />
        <!-- 避免乱码 -->
        <property name="contentType" value="text/html;charset=UTF-8" />

        <!--默认使用layout模板,可以使用#set($layout="/layout/default.vm") 使用自定义模板-->
        <property name="layoutUrl" value="base_layout.vm" />
        <!-- layoutKey设定模板文件键值,设定该值后就可以在vm文件中使用该键值设置模板路径。
        <property name="layoutKey" value="."></property>-->
        <!-- screenContentKey表示指定vm文件显示位置 -->
        <property name="screenContentKey" value="screen_content" />

        <property name="exposeSpringMacroHelpers" value="true" />
        <property name="dateToolAttribute" value="dateTool" />
        <property name="numberToolAttribute" value="numberTool" />
        <property name="exposeRequestAttributes" value="true" />
        <property name="exposeSessionAttributes" value="true" />
        <property name="requestContextAttribute" value="rc" /><!--request属性引用名称 -->

    </bean>

2. java.lang.NullPointerException

Caused by: java.lang.NullPointerException
at org.springframework.web.servlet.view.velocity.VelocityToolboxView.createVelocityContext(VelocityToolboxView.java:111)
at org.springframework.web.servlet.view.velocity.VelocityView.renderMergedTemplateModel(VelocityView.java:287)
at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
... 23 more

网上也没有查到资料,于是调试了下源码发现在类org.apache.velocity.tools.view.servlet.ServletToolboxManager中读取这个文件使用servletContext.getResourceAsStream这个API来读取的,这样问题就清楚了,开始以为是用类加载器的方式读取的。具体servletContext.getResourceAsStream如何使用大家可以看其他资料,这里不再赘述。不过后来我回头看别人的配置文档时,的确发现他们在配置这个文件路径时使用的是项目的相对路径,于是我将这个路径改成:<property name="toolboxConfigLocation" value="/WEB-INF/classes/toolbox.xml" />

3. Cannot find Velocity template for URL [layout.vm]

springmvc整合velocity的时候出现了以下错误 Cannot find Velocity template for URL [layout.vm]: Did you specify the correct resource loader path?; nested exception is org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'layout.vm' 读源码发现问题,我的配置是 bean id="ViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver" 这个bean会使用layout.vm布局,正确配置如下。 bean id="ViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver"

 <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/views/"/>
        <property name="configLocation" value="classpath:velocity.properties"/>
    </bean>

    <!-- 配置视图的显示 -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
        <!-- 如果配置了toolbox.xml则在velocity模板中可直接使用java后台代码了 -->
        <property name="toolboxConfigLocation" value="/WEB-INF/classes/toolbox.xml" />
        <property name="suffix" value=".vm" />
        <!-- 避免乱码 -->
        <property name="contentType" value="text/html;charset=UTF-8" />

        <!--默认使用layout模板,可以使用#set($layout="/layout/default.vm") 使用自定义模板-->
        <property name="layoutUrl" value="base_layout.vm" />
        <!-- layoutKey设定模板文件键值,设定该值后就可以在vm文件中使用该键值设置模板路径。
        <property name="layoutKey" value="."></property>-->
        <!-- screenContentKey表示指定vm文件显示位置 -->
        <property name="screenContentKey" value="screen_content" />

        <property name="exposeSpringMacroHelpers" value="true" />
        <property name="dateToolAttribute" value="dateTool" />
        <property name="numberToolAttribute" value="numberTool" />
        <property name="exposeRequestAttributes" value="true" />
        <property name="exposeSessionAttributes" value="true" />
        <property name="requestContextAttribute" value="rc" /><!--request属性引用名称 -->

    </bean>

调整为

 <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/views/"/>
        <property name="configLocation" value="classpath:velocity.properties"/>
    </bean>

    <!-- 配置视图的显示 -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
        <!-- 如果配置了toolbox.xml则在velocity模板中可直接使用java后台代码了 -->
        <property name="toolboxConfigLocation" value="/WEB-INF/classes/toolbox.xml" />
        <property name="suffix" value=".vm" />
        <!-- 避免乱码 -->
        <property name="contentType" value="text/html;charset=UTF-8" />


    </bean>