Spring Framework имеет встроенную интеграцию для использования Spring MVC с любой библиотекой шаблонизации, которая может выполняться на основе механизма выполнения скриптов по спецификации JSR-223 в Java. Мы протестировали следующие библиотеки шаблонизации на различных механизмах выполнения скриптов:
Библиотека скриптов | Механизм выполнения скриптов |
---|---|
ScriptEngine
и Invocable
.Требования
Необходимо обеспечить наличие механизма выполнения скриптов в своем classpath, детали которого зависят от механизма выполнения скриптов:
-
Механизм обработки JavaScript под названием Nashorn поставляется вместе с Java 8+. Настоятельно рекомендуется использовать последний доступный выпуск обновления.
-
JRuby необходимо добавить в качестве зависимости для обеспечения поддержки языка Ruby.
-
Jython необходимо добавить в качестве зависимости для обеспечения поддержки языка Python.
-
Для обеспечения поддержки скриптов Kotlin следует добавить зависимость
org.jetbrains.kotlin:kotlin-script-util
и файлMETA-INF/services/javax.script.ScriptEngineFactory
, содержащий строкуorg.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
. Более подробную информацию см. в этом примере.
Вам необходимо иметь библиотеку шаблонизации скриптов. Один из способов сделать это для JavaScript - WebJars.
Шаблоны скриптов
Вы можете объявить бин ScriptTemplateConfigurer
, чтобы задать, какой механизм выполнения скриптов использовать, какие файлы скриптов загружать, какую функцию вызывать для визуализации шаблонов и так далее. В следующем примере используются шаблоны Mustache и механизм обработки скриптов JavaScript под названием Nashorn:
@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, как показано в следующем примере:
@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 требует компиляции шаблонов перед их использованием и требует полизаполнение для эмуляции некоторых возможностей браузера, которые недоступны в механизме выполнения скриптов на стороне сервера.
В следующем примере показано, как это сделать:
@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
}
}
sharedEngine
в false
необходима при использовании небезопасных для потоков механизмов выполнения скриптов с библиотеками шаблонов, не рассчитанными на параллелизм, например, Handlebars или React, работающие на Nashorn. В этом случае требуется обновление Java SE 8 update 60 из-за этого бага, но обычно в любом случае рекомендуется использовать последний выпуск патча Java SE.polyfill.js
определяет только объект window
, необходимый Handlebars для правильной работы, следующим образом:
var window = {};
Эта базовая реализация render.js
компилирует шаблон перед его использованием. Реализация, пригодная к производственному использованию, также должна хранить любые повторно используемые кэшированные шаблоны или предварительно скомпилированные шаблоны. Это можно сделать на стороне скрипта (и обработать любую необходимую вам настройку – например, управление конфигурацией шаблонизатора). В следующем примере показано, как это сделать:
function render(template, model) {
var compiledTemplate = Handlebars.compile(template);
return compiledTemplate(model);
}
Ознакомьтесь с модульными тестами Spring Framework, Java и ресурсами, чтобы просмотреть больше примеров конфигурации.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ