|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
脚本视图
要求
您需要将脚本引擎放在类路径(classpath)中,具体细节因脚本引擎而异:
-
Nashorn JavaScript 引擎随 Java 8+ 一同提供。强烈建议使用最新的更新版本。
-
应将 JRuby 添加为依赖项以支持 Ruby。
-
Jython 应作为依赖项添加以支持 Python。
-
应添加
org.jetbrains.kotlin:kotlin-script-util依赖项,以及一个包含META-INF/services/javax.script.ScriptEngineFactory行的org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory文件,以支持 Kotlin 脚本。更多详情请参见此示例。
你需要拥有脚本模板库。对于 JavaScript 来说,一种实现方式是通过 WebJars。
脚本模板
你可以声明一个 ScriptTemplateConfigurer Bean 来指定要使用的脚本引擎、要加载的脚本文件、用于渲染模板的函数等。
以下示例使用 Mustache 模板和 Nashorn JavaScript 引擎:
-
Java
-
Kotlin
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@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;
}
}
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.scriptTemplate()
}
@Bean
fun configurer() = ScriptTemplateConfigurer().apply {
engineName = "nashorn"
setScripts("mustache.js")
renderObject = "Mustache"
renderFunction = "render"
}
}
以下示例展示了 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>
对于 Java 配置和 XML 配置,控制器的写法并无不同,如下例所示:
-
Java
-
Kotlin
@Controller
public class SampleController {
@GetMapping("/sample")
public String test(Model model) {
model.addAttribute("title", "Sample title");
model.addAttribute("body", "Sample body");
return "template";
}
}
@Controller
class SampleController {
@GetMapping("/sample")
fun test(model: Model): String {
model["title"] = "Sample title"
model["body"] = "Sample body"
return "template"
}
}
以下示例展示了 Mustache 模板:
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<p>{{body}}</p>
</body>
</html>
render 函数将使用以下参数进行调用:
-
String template:模板内容 -
Map model:视图模型 -
RenderingContext renderingContext:RenderingContext,它提供对应用程序上下文、区域设置、模板加载器以及 URL(自 5.0 版本起)的访问权限。
Mustache.render() 原生兼容此签名,因此你可以直接调用它。
如果你的模板技术需要一些自定义配置,你可以提供一个脚本来实现自定义的渲染函数。例如,Handlebars 在使用模板之前需要先对其进行编译,并且需要一个polyfill来模拟服务器端脚本引擎中不可用的某些浏览器功能。
下面的例子展示了如何做到这一点:
-
Java
-
Kotlin
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@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;
}
}
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.scriptTemplate()
}
@Bean
fun configurer() = ScriptTemplateConfigurer().apply {
engineName = "nashorn"
setScripts("polyfill.js", "handlebars.js", "render.js")
renderFunction = "render"
isSharedEngine = false
}
}
当使用非线程安全的脚本引擎与未针对并发设计的模板库(例如在 Nashorn 上运行的 Handlebars 或 React)时,需要将 sharedEngine 属性设置为 false。在这种情况下,由于此 bug,需要 Java SE 8 更新版本 60 或更高版本,但无论如何,通常都建议使用较新的 Java SE 补丁版本。 |
polyfill.js 仅定义了 Handlebars 正常运行所需的 window 对象,如下所示:
var window = {};
这个基本的 render.js 实现在使用模板之前对其进行编译。一个可用于生产环境的实现还应缓存任何重复使用的模板或预编译的模板。
你可以在脚本端实现这一点(并处理所需的任何自定义操作,例如管理模板引擎的配置)。以下示例展示了如何实现:
function render(template, model) {
var compiledTemplate = Handlebars.compile(template);
return compiledTemplate(model);
}