19.6 Script 模板

可以使用Spring将任何在JSR-223脚本引擎上运行的模板库集成到Web应用程序中。以下以广泛的方式描述如何做到这一点。脚本引擎必须实现ScriptEngine和Invocable接口。

已通过以下测试:

  • H andlebars running on Nashorn
  • Mustache running on Nashorn
  • React running on Nashorn
  • EJS running on Nashorn
  • ERB running on JRuby
  • String templates running on Jython

19.6.1依赖关系

为了能够使用脚本模板集成,您需要在您的类路径中提供脚本引擎:

  • Nashorn Javascript引擎内置Java 8+。强烈建议使用最新的更新版本。
  • Rhino Javascript引擎内建Java 6和Java 7.请注意,不建议使用Rhino,因为它不支持运行大多数模板引擎。
  • 应该添加JRuby依赖以获得Ruby的支持。
  • 应该添加Jython依赖关系,以获得Python的支持。

您还需要为基于脚本的模板引擎添加依赖关系。例如,对于Javascript,您可以使用WebJars添加Maven / Gradle依赖关系,以使您的javascript库在类路径中可用。

19.6.2如何集成基于脚本的模板

为了能够使用脚本模板,您必须对其进行配置,以便指定各种参数,如要使用的脚本引擎,要加载的脚本文件以及应该调用哪些函数来呈现模板。这是由于ScriptTemplateConfigurer bean和可选的脚本文件。

例如,为了渲染Mustache模板,感谢Java 8+提供的Nashorn Javascript引擎,您应该声明以下配置:

@Configuration
@EnableWebMvc
public class MustacheConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.scriptTemplate();
    }

    @Bean
    public ScriptTemplateConfigurer configurer() {
        ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
        configurer.setEngineName("nashorn");
        configurer.setScripts("mustache.js");
        configurer.setRenderObject("Mustache");
        configurer.setRenderFunction("render");
        return configurer;
    }
}

XML 表示如下:

<mvc:annotation-driven/>

<mvc:view-resolvers>
    <mvc:script-template/>
</mvc:view-resolvers>

<mvc:script-template-configurer engine-name="nashorn" render-object="Mustache" render-function="render">
    <mvc:script location="mustache.js"/>
</mvc:script-template-configurer>

你期望的controller:

@Controller
public class SampleController {

    @RequestMapping
    public ModelAndView test() {
        ModelAndView mav  = new ModelAndView();
        mav.addObject("title", "Sample title").addObject("body", "Sample body");
        mav.setViewName("template.html");
        return mav;
    }
}

而Mustache模板是:

<html>
    <head>
        <title>{{title}}</title>
    </head>
    <body>
        <p>{{body}}</p>
    </body>
</html>

使用以下参数调用render函数:

  • 字符串模板:模板内容
  • 地图模型:视图模型
  • String url:模板url(自4.2.2起)

Mustache.render()与此签名本身兼容,因此您可以直接调用它。

如果您的模板技术需要一些自定义,您可以提供一个实现自定义渲染功能的脚本。例如,Handlerbars需要在使用它们之前编译模板,并且需要一个polyfill才能模拟服务器端脚本引擎中不可用的一些浏览器设施。

@Configuration
@EnableWebMvc
public class MustacheConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.scriptTemplate();
    }

    @Bean
    public ScriptTemplateConfigurer configurer() {
        ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
        configurer.setEngineName("nashorn");
        configurer.setScripts("polyfill.js", "handlebars.js", "render.js");
        configurer.setRenderFunction("render");
        configurer.setSharedEngine(false);
        return configurer;
    }
}

[注意]

如果使用非线程安全的脚本引擎,而不使用非并行设计的模板库(例如,在Nashorn上运行的Handlebars或React),则需要将sharedEngine属性设置为false。在这种情况下,由于这个错误,需要Java 8u60或更高版本。

polyfill.js仅定义Handlebars需要正确运行的窗口对象:

var window = {};

这个基本的render.js实现在使用之前编译模板。生产就绪实现还应该存储和重新使用缓存的模板/预编译模板。这可以在脚本端完成,以及您需要的任何定制(例如,管理模板引擎配置)。

function render(template, model) {
    var compiledTemplate = Handlebars.compile(template);
    return compiledTemplate(model);
}