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引擎,您应该声明以下配置:

  1. @Configuration
  2. @EnableWebMvc
  3. public class MustacheConfig extends WebMvcConfigurerAdapter {
  4. @Override
  5. public void configureViewResolvers(ViewResolverRegistry registry) {
  6. registry.scriptTemplate();
  7. }
  8. @Bean
  9. public ScriptTemplateConfigurer configurer() {
  10. ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
  11. configurer.setEngineName("nashorn");
  12. configurer.setScripts("mustache.js");
  13. configurer.setRenderObject("Mustache");
  14. configurer.setRenderFunction("render");
  15. return configurer;
  16. }
  17. }

XML 表示如下:

  1. <mvc:annotation-driven/>
  2. <mvc:view-resolvers>
  3. <mvc:script-template/>
  4. </mvc:view-resolvers>
  5. <mvc:script-template-configurer engine-name="nashorn" render-object="Mustache" render-function="render">
  6. <mvc:script location="mustache.js"/>
  7. </mvc:script-template-configurer>

你期望的controller:

  1. @Controller
  2. public class SampleController {
  3. @RequestMapping
  4. public ModelAndView test() {
  5. ModelAndView mav = new ModelAndView();
  6. mav.addObject("title", "Sample title").addObject("body", "Sample body");
  7. mav.setViewName("template.html");
  8. return mav;
  9. }
  10. }

而Mustache模板是:

  1. <html>
  2. <head>
  3. <title>{{title}}</title>
  4. </head>
  5. <body>
  6. <p>{{body}}</p>
  7. </body>
  8. </html>

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

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

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

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

  1. @Configuration
  2. @EnableWebMvc
  3. public class MustacheConfig extends WebMvcConfigurerAdapter {
  4. @Override
  5. public void configureViewResolvers(ViewResolverRegistry registry) {
  6. registry.scriptTemplate();
  7. }
  8. @Bean
  9. public ScriptTemplateConfigurer configurer() {
  10. ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
  11. configurer.setEngineName("nashorn");
  12. configurer.setScripts("polyfill.js", "handlebars.js", "render.js");
  13. configurer.setRenderFunction("render");
  14. configurer.setSharedEngine(false);
  15. return configurer;
  16. }
  17. }

[注意]

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

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

  1. var window = {};

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

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