6

如何使用 Spring MVC、Sitemesh 和 Freemarker 将 spring.ftl 宏导入 Freemarker 模板页面?

我已经根据Ted Young 的配置示例使用 Sitemesh 和 Freemarker 配置了一个 Spring MVC 应用程序。根据Spring MVC/Freemarker集成参考,需要导入 spring.ftl 宏以便通过 <@spring.bind "command.name"/> 将支持模型绑定到视图。但是,这样做:

<#import "/spring.ftl" as spring>
<@spring.bind "command.user"/>

导致此异常:

org.springframework.web.util.NestedServletException: 
Request processing failed; nested exception is freemarker.
template.TemplateException: Error reading imported file spring.ftl

其他人也遇到过这个问题,但我还没有在谷歌土地上找到解决方案。我也尝试使用这种技术(压缩 spring.ftl,将其放在 META-INF/lib 中,并将 zip 添加到构建路径),但它似乎没有成功。

谢谢!

4

3 回答 3

4

问题是spring不知道在哪里看spring.ftl文件:这是我使用Boot的MVC项目的自定义配置

/**
 * Otras configuraciones de la aplicaciones web, incluyendo algunas definidas en
 * xml. Usar @ImportResource("classpath:/extra-config.xml") en caso de quererse
 * importar configuracion en xml
 */
@Configuration 
@PropertySource("classpath:application.properties")
public class WebAppConfig
{
    @Autowired
    private ServletContext context;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer placeHolderConfigurer = new PropertySourcesPlaceholderConfigurer(); 
        return placeHolderConfigurer;
    }

   @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() throws IOException, TemplateException 
    {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer()
        {

            @Override
            protected void postProcessConfiguration(freemarker.template.Configuration config) throws IOException, TemplateException
            {
                WebappTemplateLoader WebAppTplLoader = new WebappTemplateLoader(context, "/WEB-INF/ftl");
                ClassTemplateLoader classTplLoader = new ClassTemplateLoader(context.getClassLoader(), "/templates");
                ClassTemplateLoader baseMvcTplLoader = new ClassTemplateLoader(FreeMarkerConfigurer.class, "");
                MultiTemplateLoader mtl = new MultiTemplateLoader(new TemplateLoader[]
                {
                    WebAppTplLoader,
                    classTplLoader,
                    baseMvcTplLoader
                });  
                config.setTemplateLoader(mtl);
            }
        };
        configurer.setDefaultEncoding("UTF-8"); 
        configurer.setPreferFileSystemAccess(false); 
        return configurer; 
    }

    @Bean
    public FreeMarkerViewResolver viewResolver()
    {
         FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver(); 
         viewResolver.setExposeSpringMacroHelpers(true);  
         viewResolver.setExposeRequestAttributes(true);
         viewResolver.setPrefix("");
         viewResolver.setSuffix(".ftl");
         viewResolver.setContentType("text/html;charset=UTF-8");
         return viewResolver;
    }
}

前 2 个加载器允许从 "/WEB-INF/ftl".ftl文件和. 如果您想在 freemarker 中使用安全标签,则重点是以下两行:warjarsrc/resources/templates

         viewResolver.setExposeSpringMacroHelpers(true);  
         viewResolver.setExposeRequestAttributes(true);

baseMvcTplLoader以及获取spring.ftlfrom的加载程序org.springframework.web.servlet.view.freemarker。我建议在一些示例项目文档中探索 ftl 模板,以了解其spring.ftl工作原理。

占位符的配置与 freemarker 配置无关,但它对于src/resources/application.properties使用@Value 注解从变量中注入值非常有用。

有了这个,您可以使用freemarker模板中的所有弹簧力量。

于 2015-07-31T15:59:02.087 回答
0

我喜欢默认包含的 spring.ftl,而无需在每个视图中手动添加它。在您的配置中。

像这样定义你的 freemarkerConfigurer。

   @Bean(name = "freemarkerConfig")
public FreeMarkerConfigurer freemarkerConfig() {
    FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
    configurer.setTemplateLoaderPath("/WEB-INF/views/");
    Map<String, Object> map = new HashMap<>();
    map.put("xml_escape", new XmlEscape());
    configurer.setFreemarkerVariables(map)
    def settings = new Properties()
    settings['auto_import']  =  'spring.ftl as spring, layout/application.ftl as l'
    configurer.setFreemarkerSettings(settings)
    println "returning freemarker config"
    return configurer;
}
于 2016-02-09T18:57:47.507 回答
-3
<#import "spring.ftl" as spring/>

没有/

于 2012-02-12T23:48:19.623 回答