Thymeleaf

Thymeleaf — це сучасний шаблонізатор Java на стороні сервера, який спирається на природні HTML-шаблони, які можна попередньо переглянути в браузері подвійним клацанням миші, що дуже зручно при самостійній роботі над шаблонами інтерфейсу користувача (наприклад, дизайнеру) без необхідності мати працюючий сервер. Thymeleaf пропонує широкий набір функцій, активно розвивається та підтримується. Більш детальну вступну інформацію можна знайти на домашній сторінці проєкту Thymeleaf.

Інтеграція Thymeleaf із Spring WebFlux керується проєктом Thymeleaf. Конфігурація передбачає кілька оголошень бінів, таких як SpringResourceTemplateResolver, SpringWebFluxTemplateEngine та ThymeleafReactiveViewResolver. Для отримання більш детальної інформації див. розділ "Thymeleaf+Spring" та анонс інтеграції з WebFlux.

FreeMarker

Apache FreeMarker — це шаблонізатор для генерації будь-якого виду текстового виведення від HTML до електронної пошти та ін. Spring Framework має вбудовану інтеграцію для використання Spring WebFlux з шаблонами з FreeMarker.

Конфігурація подання

В наступному прикладі показано, як можна налаштувати FreeMarker як технологію подання:

Java

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.freeMarker();
}
// Конфігуруємо FreeMarker...
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("classpath:/templates/freemarker");
return configurer;
}
}
Kotlin

@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.freeMarker()
}
// Конфігуруємо FreeMarker...
@Bean
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("classpath:/templates/freemarker")
}
}

Твої шаблони повинні зберігатися в директорії, вказаній FreeMarkerConfigurer, як це показано в попередньому прикладі. Враховуючи попередню конфігурацію, якщо контролер повертає ім'я подання welcome, перетворювач шукає шаблон classpath:/templates/freemarker/welcome.ftl.

Конфігурація FreeMarker

Можна передати "Settings" та "SharedVariable" обробника FreeMarker безпосередньо до об'єкта Configuration обробника FreeMarker (який керується Spring), встановивши відповідні властивості біна в FreeMarkerConfigurer. Для властивості freemarkerSettings потрібен об'єкт java.util.Properties, а для якості freemarkerVariablesjava.util.Map. У цьому прикладі показано, як використовувати FreeMarkerConfigurer:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
// ...
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
Map<String, Object> variables = new HashMap<>();
variables.put("xml_escape", new XmlEscape());
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("classpath:/templates");
configurer.setFreemarkerVariables(variables);
return configurer;
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
// ...
@Bean
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("classpath:/templates")
setFreemarkerVariables(mapOf("xml_escape" to XmlEscape()))
}
}

Подробиці про налаштування та змінні, які застосовуються до об'єкта Configuration, див. у документації з FreeMarker.

Обробка форм

Spring передбачає бібліотеку тегів для використання в JSP, яка містить, серед іншого, елемент <spring:bind/>. Цей елемент насамперед дозволяє формам виводити на екран значення з базових об'єктів форми та відображати результати невдалих перевірок з Validator на вебрівні або бізнес-рівні. Spring також має підтримку тієї ж функціональності FreeMarker, з додатковими зручними макросами для генерації самих елементів введення форми.

Макроси прив'язки

Засоби підтримки стандартного набору макросів знаходяться у файлі spring- webflux.jar для FreeMarker, тому вони завжди доступні для відповідним чином налаштованого додатка.

Деякі макроси, визначені в бібліотеках шаблонізації в Spring, вважаються внутрішніми (приватними), але у визначеннях макросів такого обмеження нема, що робить всі макроси видимими для коду, що викликає, і користувацьких шаблонів. Наступні розділи присвячені лише тим макросам, які потрібно викликати безпосередньо з шаблонів. Якщо тобі потрібно переглянути код макросу безпосередньо, файл називається spring.ftl і знаходиться в пакеті org.springframework.web.reactive.result.view.freemarker.

Макроси форми

Для отримання детальної інформації про засоби підтримки макросів форм для шаблонів FreeMarker у Spring звернися до наступних розділів документації Spring MVC.

  • Макроси введення

  • Поля введення

  • Поля вибору

  • HTML-екранування

Скриптові подання

Spring Framework має вбудовану інтеграцію для використання Spring WebFlux з будь-якою бібліотекою шаблонизації, яка може виконуватися поверх механізму виконання скриптів за специфікацією JSR-223 в Java. У наступній таблиці представлені бібліотеки шаблонів, які ми тестували на різних механізмах виконання скриптів:

Бібліотека скриптів Механізм виконання скриптів

Handlebars

Nashorn

Mustache

Nashorn

React

Nashorn

EJS

Nashorn

ERB

JRuby

Шаблони рядків

Jython

Шаблонізація скриптів у Kotlin

Kotlin

Основне правило для інтеграції будь-якого іншого механізму виконання скриптів полягає в тому, що він повинен реалізувати інтерфейси 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:

>Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@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;
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.scriptTemplate()
}
@Bean
fun configurer() = ScriptTemplateConfigurer().apply {
engineName = "nashorn"
setScripts("mustache.js")
renderObject = "Mustache"
renderFunction = "render"
}
}

Функція render викликається з наступними параметрами:

  • String template: Зміст шаблону

    >
  • Map model: Модель представлення

  • RenderingContext renderingContext: RenderingContext, який надає доступ до контексту програми, регіональних налаштувань, завантажувача шаблонів та URL-адреси (починаючи з версії 5.0).

Mustache.render() спочатку сумісний з цією сигнатурою, тому можна викликати його безпосередньо.

Якщо твоя технологія шаблонізації вимагає певного налаштування, то можна передати скрипт, який реалізує кастомну функцію візуалізації. Наприклад, Handlerbars вимагає компіляції шаблонів перед використанням і вимагає полізаповнення для емуляції деяких можливостей браузера, які недоступні в механізмі виконання скриптів на стороні сервера. У цьому прикладі показано, як встановити кастомну функцію візуалізації:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@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;
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
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.
 var window = {};

Ця базова реалізація render.js компілює шаблон перед його використанням. Реалізація, придатна до виробничого використання, також повинна зберігати будь-які кешовані шаблони, що повторно використовуються, або попередньо скомпільовані шаблони. Це можна зробити на стороні скрипта, а також за будь-яких необхідних тобі налаштувань (наприклад, керуючи конфігурацією шаблонизатора). У цьому прикладі показано, як скомпілювати шаблон:

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

Ознайомся з модульними тестами Spring Framework, Java та ресурсами, щоб переглянути більше прикладів конфігурації.

JSON та XML

З міркувань узгодження вмісту корисно мати можливість чергувати відображення моделі з шаблоном у форматі HTML або в інших форматах (таких як JSON або XML), залежно від типу вмісту, на який клієнт робить запит. Для підтримки цієї функції Spring WebFlux передбачає HttpMessageWriterView, який можна використовувати для підключення будь-якого з доступних кодеків з spring -web, таких як Jackson2JsonEncoder, Jackson2SmileEncoder або Jaxb2XmlEncoder.

На відміну від інших технологій подання, HttpMessageWriterView не вимагає ViewResolver, а конфігурується як стандартне подання. Можна налаштувати одне або кілька таких подань за умовчанням, обернувши ними різні екземпляри HttpMessageWriter або екземпляри Encoder. Під час виконання використовується той, який відповідає типу типу, що запитується.

У більшості випадків модель містить кілька атрибутів. Щоб визначити, який з них серіалізувати, можна налаштувати HttpMessageWriterView з ім'ям атрибута моделі, який потрібно використовувати для візуалізації. Якщо модель містить лише один атрибут, то використовуватиметься саме він.