Spring WebFlux 中视图技术的使用是可插拔的。您是否决定 使用 Thymeleaf、FreeMarker 或其他一些视图技术主要是一个问题 配置更改。本章介绍与 Spring 集成的视图技术 WebFlux 中。我们假设您已经熟悉视图分辨率。
百里香叶
Thymeleaf 是一个现代服务器端 Java 模板引擎,强调自然 HTML 双击可以在浏览器中预览的模板,非常 有助于独立处理 UI 模板(例如,由设计师完成),而无需 正在运行的服务器。Thymeleaf 提供了一组广泛的功能,并且正在积极开发中 并维持。有关更完整的介绍,请参阅 Thymeleaf 项目主页。
Thymeleaf 与 Spring WebFlux 的集成由 Thymeleaf 项目管理。这
配置涉及一些 Bean 声明,例如 、 和 。有关详细信息,请参阅 Thymeleaf+Spring 和 WebFlux 集成公告。SpringResourceTemplateResolver
SpringWebFluxTemplateEngine
ThymeleafReactiveViewResolver
自由标记
Apache FreeMarker 是一个模板引擎,用于生成任何 从 HTML 到电子邮件等的文本输出类型。Spring 框架内置了 将 Spring WebFlux 与 FreeMarker 模板结合使用。
View 配置
以下示例演示如何将 FreeMarker 配置为视图技术:
-
Java
-
Kotlin
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.freeMarker();
}
// Configure FreeMarker...
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("classpath:/templates/freemarker");
return configurer;
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.freeMarker()
}
// Configure FreeMarker...
@Bean
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("classpath:/templates/freemarker")
}
}
您的模板需要存储在 , 指定的目录中
如上例所示。给定上述配置,如果您的控制器
返回视图名称 ,解析程序将查找模板。FreeMarkerConfigurer
welcome
classpath:/templates/freemarker/welcome.ftl
FreeMarker 配置
您可以通过设置适当的 bean 将 FreeMarker 的“设置”和“SharedVariables”直接传递给 FreeMarker 对象(由 Spring 管理)
Bean 上的属性。该物业要求
一个对象,并且该属性需要 .以下示例演示如何使用:Configuration
FreeMarkerConfigurer
freemarkerSettings
java.util.Properties
freemarkerVariables
java.util.Map
FreeMarkerConfigurer
-
Java
-
Kotlin
@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;
}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
// ...
@Bean
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("classpath:/templates")
setFreemarkerVariables(mapOf("xml_escape" to XmlEscape()))
}
}
请参阅 FreeMarker 文档,了解适用于
对象。Configuration
表单处理
Spring 提供了一个用于 JSP 的标签库,其中包含一个元素。此元素主要让表单显示来自
表单支持对象,并显示来自
Web 或业务层。Spring 还支持 FreeMarker 中的相同功能,
具有用于生成表单输入元素本身的额外便利宏。<spring:bind/>
Validator
绑定宏
文件中维护了一组标准的宏
FreeMarker,因此它们始终可用于适当配置的应用程序。spring-webflux.jar
Spring 模板库中定义的某些宏被视为内部宏
(private),但宏定义中不存在此类范围,使所有宏都可见
调用代码和用户模板。以下各节仅重点介绍宏
您需要直接从模板中调用。如果要查看宏代码
直接调用该文件并位于包中。spring.ftl
org.springframework.web.reactive.result.view.freemarker
有关绑定支持的其他详细信息,请参阅 Spring MVC 的简单绑定。
脚本视图
Spring Framework 具有内置集成,可用于将 Spring WebFlux 与任何 可以在 JSR-223 Java 脚本引擎上运行的模板库。 下表显示了我们在不同脚本引擎上测试的模板库:
脚本库 | 脚本引擎 |
---|---|
集成任何其他脚本引擎的基本规则是它必须实现 and 接口。ScriptEngine Invocable |
要求
您需要在类路径上安装脚本引擎,其详细信息因脚本引擎而异:
-
Nashorn JavaScript 引擎提供 Java 8+的。强烈建议使用可用的最新更新版本。
-
JRuby 应该被添加为 Ruby 支持的依赖项。
-
Jython 应添加为 Python 支持的依赖项。
-
org.jetbrains.kotlin:kotlin-script-util
依赖项和包含一行的文件应添加以支持 Kotlin 脚本。有关详细信息,请参阅此示例。META-INF/services/javax.script.ScriptEngineFactory
org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
您需要有脚本模板库。对 JavaScript 执行此操作的一种方法是 通过 WebJars。
脚本模板
你可以声明一个 bean 来指定要使用的脚本引擎,
要加载的脚本文件、要调用什么函数来呈现模板等。
以下示例使用 Mustache 模板和 Nashorn JavaScript 引擎:ScriptTemplateConfigurer
-
Java
-
Kotlin
@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;
}
}
@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 在使用模板之前需要编译模板,并且需要 polyfill 才能模拟一些 浏览器功能在服务器端脚本引擎中不可用。 以下示例演示如何设置自定义呈现函数:
-
Java
-
Kotlin
@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;
}
}
@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
}
}
使用非线程安全时,需要将该属性设置为
脚本引擎的模板库不是为并发而设计的,例如 Handlebars 或
在 Nashorn 上运行的反应。在这种情况下,由于此错误,需要 Java SE 8 更新 60,但通常是
在任何情况下,都建议使用最新的 Java SE 补丁版本。sharedEngine false |
polyfill.js
仅定义 Handlebars 正常运行所需的对象,
如以下代码片段所示:window
var window = {};
此基本实现在使用模板之前对其进行编译。一个生产
就绪实现还应存储和重用缓存的模板或预编译的模板。
这可以在脚本端完成,也可以在您需要的任何自定义(管理
例如,模板引擎配置)。
以下示例演示如何编译模板:render.js
function render(template, model) {
var compiledTemplate = Handlebars.compile(template);
return compiledTemplate(model);
}
JSON 和 XML
出于内容协商的目的,能够交替使用是很有用的
在使用 HTML 模板或其他格式(如 JSON 或 XML)呈现模型之间,
取决于客户端请求的内容类型。为了支持这样做,Spring WebFlux
提供了 ,您可以使用它从 中插入任何可用的编解码器,例如 、 、
或。HttpMessageWriterView
spring-web
Jackson2JsonEncoder
Jackson2SmileEncoder
Jaxb2XmlEncoder
与其他视图技术不同,它不需要,而是配置为默认视图。您可以
配置一个或多个此类默认视图,包装不同的实例
或实例。在运行时使用与请求的内容类型匹配的内容类型。HttpMessageWriterView
ViewResolver
HttpMessageWriter
Encoder
在大多数情况下,一个模型包含多个属性。要确定要序列化的一个,
您可以使用要用于的模型属性的名称进行配置
渲染。如果模型仅包含一个属性,则使用该属性。HttpMessageWriterView