指令碼檢視
要求
你的類路徑中需要包含指令碼引擎,具體取決於指令碼引擎的不同
-
Java 8+ 提供了 Nashorn JavaScript 引擎。強烈建議使用最新的可用更新版本。
-
對於 Ruby 支援,應將 JRuby 新增為依賴。
-
對於 Python 支援,應將 Jython 新增為依賴。
-
對於 Kotlin 指令碼支援,應新增
org.jetbrains.kotlin:kotlin-script-util
依賴以及包含org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
行的META-INF/services/javax.script.ScriptEngineFactory
檔案。有關更多詳細資訊,請參閱此示例。
你需要包含指令碼模板庫。對於 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>
呼叫渲染函式時使用以下引數:
-
String template
:模板內容 -
Map model
:檢視模型 -
RenderingContext renderingContext
:RenderingContext
,用於訪問應用程式上下文、區域設定、模板載入器和 URL(從 5.0 版本開始)
Mustache.render()
原生相容此簽名,因此你可以直接呼叫它。
如果你的模板技術需要一些定製,你可以提供一個實現自定義渲染函式的指令碼。例如,Handlerbars 需要在使用前編譯模板,並且需要一個 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 update 60,但無論如何通常建議使用最新的 Java SE 修補版本。 |
polyfill.js
僅定義了 Handlebars 正常執行所需的 window
物件,如下所示:
var window = {};
這個基本的 render.js
實現在使用模板前對其進行編譯。一個生產就緒的實現還應該儲存任何重用的快取模板或預編譯模板。你可以在指令碼端進行此操作(並處理所需的任何定製——例如,管理模板引擎配置)。以下示例展示瞭如何做到這一點:
function render(template, model) {
var compiledTemplate = Handlebars.compile(template);
return compiledTemplate(model);
}