此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10

此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10

Spring WebFlux 中视图技术的使用是可插拔的。您是否决定 使用 Thymeleaf、FreeMarker 或其他一些视图技术主要是一个问题 配置更改。本章介绍与 Spring 集成的视图技术 WebFlux 中。我们假设您已经熟悉视图分辨率

百里香叶

Thymeleaf 是一个现代服务器端 Java 模板引擎,强调自然 HTML 双击可以在浏览器中预览的模板,非常 有助于独立处理 UI 模板(例如,由设计师完成),而无需 正在运行的服务器。Thymeleaf 提供了一组广泛的功能,并且正在积极开发中 并维持。有关更完整的介绍,请参阅 Thymeleaf 项目主页。

Thymeleaf 与 Spring WebFlux 的集成由 Thymeleaf 项目管理。这 配置涉及一些 Bean 声明,例如 、 和 。有关详细信息,请参阅 Thymeleaf+Spring 和 WebFlux 集成公告SpringResourceTemplateResolverSpringWebFluxTemplateEngineThymeleafReactiveViewResolver

自由标记

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")
	}
}

您的模板需要存储在 , 指定的目录中 如上例所示。给定上述配置,如果您的控制器 返回视图名称 ,解析程序将查找模板。FreeMarkerConfigurerwelcomeclasspath:/templates/freemarker/welcome.ftl

FreeMarker 配置

您可以通过设置适当的 bean 将 FreeMarker 的“设置”和“SharedVariables”直接传递给 FreeMarker 对象(由 Spring 管理) Bean 上的属性。该物业要求 一个对象,并且该属性需要 .以下示例演示如何使用:ConfigurationFreeMarkerConfigurerfreemarkerSettingsjava.util.PropertiesfreemarkerVariablesjava.util.MapFreeMarkerConfigurer

  • 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.ftlorg.springframework.web.reactive.result.view.freemarker

有关绑定支持的其他详细信息,请参阅 Spring MVC 的简单绑定

表单宏

有关 Spring 对 FreeMarker 模板的表单宏支持的详细信息,请参阅以下内容 Spring MVC 文档的部分。

脚本视图

Spring Framework 具有内置集成,可用于将 Spring WebFlux 与任何 可以在 JSR-223 Java 脚本引擎上运行的模板库。 下表显示了我们在不同脚本引擎上测试的模板库:

脚本库 脚本引擎

车把

纳斯霍恩

胡子

纳斯霍恩

反应

纳斯霍恩

EJS系列

纳斯霍恩

雇员再培训局

JRuby

字符串模板

Jython (英语)

Kotlin 脚本模板

Kotlin

集成任何其他脚本引擎的基本规则是它必须实现 and 接口。ScriptEngineInvocable

要求

您需要在类路径上安装脚本引擎,其详细信息因脚本引擎而异:

  • Nashorn JavaScript 引擎提供 Java 8+的。强烈建议使用可用的最新更新版本。

  • JRuby 应该被添加为 Ruby 支持的依赖项。

  • Jython 应添加为 Python 支持的依赖项。

  • org.jetbrains.kotlin:kotlin-script-util依赖项和包含一行的文件应添加以支持 Kotlin 脚本。有关详细信息,请参阅此示例META-INF/services/javax.script.ScriptEngineFactoryorg.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 renderingContextRenderingContext,用于访问应用程序上下文、区域设置、模板加载程序和 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 补丁版本。sharedEnginefalse

polyfill.js仅定义 Handlebars 正常运行所需的对象, 如以下代码片段所示:window

var window = {};

此基本实现在使用模板之前对其进行编译。一个生产 就绪实现还应存储和重用缓存的模板或预编译的模板。 这可以在脚本端完成,也可以在您需要的任何自定义(管理 例如,模板引擎配置)。 以下示例演示如何编译模板:render.js

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

查看 Spring Framework 单元测试、Java资源, 获取更多配置示例。

脚本库 脚本引擎

车把

纳斯霍恩

胡子

纳斯霍恩

反应

纳斯霍恩

EJS系列

纳斯霍恩

雇员再培训局

JRuby

字符串模板

Jython (英语)

Kotlin 脚本模板

Kotlin

集成任何其他脚本引擎的基本规则是它必须实现 and 接口。ScriptEngineInvocable
使用非线程安全时,需要将该属性设置为 脚本引擎的模板库不是为并发而设计的,例如 Handlebars 或 在 Nashorn 上运行的反应。在这种情况下,由于此错误,需要 Java SE 8 更新 60,但通常是 在任何情况下,都建议使用最新的 Java SE 补丁版本。sharedEnginefalse

JSON 和 XML

出于内容协商的目的,能够交替使用是很有用的 在使用 HTML 模板或其他格式(如 JSON 或 XML)呈现模型之间, 取决于客户端请求的内容类型。为了支持这样做,Spring WebFlux 提供了 ,您可以使用它从 中插入任何可用的编解码器,例如 、 、 或。HttpMessageWriterViewspring-webJackson2JsonEncoderJackson2SmileEncoderJaxb2XmlEncoder

与其他视图技术不同,它不需要,而是配置为默认视图。您可以 配置一个或多个此类默认视图,包装不同的实例 或实例。在运行时使用与请求的内容类型匹配的内容类型。HttpMessageWriterViewViewResolverHttpMessageWriterEncoder

在大多数情况下,一个模型包含多个属性。要确定要序列化的一个, 您可以使用要用于的模型属性的名称进行配置 渲染。如果模型仅包含一个属性,则使用该属性。HttpMessageWriterView