此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10spring-doc.cadn.net.cn

查看技术

Spring WebFlux 中视图的渲染是可插拔的。无论您决定 使用 Thymeleaf、FreeMarker 或其他一些视图技术主要是 配置更改。本章介绍与 Spring 集成的视图技术 WebFlux 的。spring-doc.cadn.net.cn

有关视图渲染的更多上下文,请参阅视图分辨率spring-doc.cadn.net.cn

Spring WebFlux 应用程序的视图位于内部信任边界内 的应用程序。视图可以访问应用程序上下文中的 bean,并且作为 因此,我们不建议在以下应用程序中使用 Spring WebFlux 模板支持 模板可由外部源编辑,因为这可能会产生安全隐患。

胸腺叶

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

Thymeleaf 与 Spring WebFlux 的集成由 Thymeleaf 项目管理。这 配置涉及一些 bean 声明,例如SpringResourceTemplateResolver,SpringWebFluxTemplateEngineThymeleafReactiveViewResolver.有关更多详细信息,请参阅 Thymeleaf+Spring 和 WebFlux 集成公告spring-doc.cadn.net.cn

自由标记

Apache FreeMarker 是一个模板引擎,用于生成任何 从 HTML 到电子邮件等的文本输出。Spring 框架内置了 将 Spring WebFlux 与 FreeMarker 模板一起使用的集成。spring-doc.cadn.net.cn

查看配置

以下示例展示了如何将 FreeMarker 配置为视图技术:spring-doc.cadn.net.cn

@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模板。spring-doc.cadn.net.cn

FreeMarker 配置

您可以将 FreeMarker 的“设置”和“共享变量”直接传递给 FreeMarkerConfiguration对象(由 Spring 管理)通过设置适当的 bean 属性FreeMarkerConfigurer豆。这freemarkerSettings属性要求 一个java.util.Properties对象,而freemarkerVariables属性需要java.util.Map.以下示例显示如何使用FreeMarkerConfigurer:spring-doc.cadn.net.cn

@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-doc.cadn.net.cn

表单处理

Spring 提供了一个用于 JSP 的标签库,其中包含一个<spring:bind/>元素。 此元素主要允许表单显示来自form-backing 对象的值,并显示来自Validator在 Web 或业务层。Spring 还支持 FreeMarker 中的相同功能,具有额外的便利宏,用于生成表单输入元素本身。spring-doc.cadn.net.cn

绑定宏

一组标准宏在spring-webflux.jar文件FreeMarker,因此它们始终可用于适当配置的应用程序。spring-doc.cadn.net.cn

Spring 模板库中定义的一些宏被认为是内部的(私有),但宏定义中不存在这样的范围,使所有宏都可见到调用代码和用户模板。以下部分仅关注宏您需要直接从模板中调用。如果您想查看宏代码直接,则该文件被调用spring.ftl并且位于org.springframework.web.reactive.result.view.freemarker包。spring-doc.cadn.net.cn

有关绑定支持的其他详细信息,请参阅 Spring MVC 的简单绑定spring-doc.cadn.net.cn

表单宏

有关 Spring 对 FreeMarker 模板的表单宏支持的详细信息,请参阅以下Spring MVC 文档的部分。spring-doc.cadn.net.cn

脚本视图

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

脚本库 脚本引擎

车把spring-doc.cadn.net.cn

纳斯霍恩spring-doc.cadn.net.cn

胡子spring-doc.cadn.net.cn

纳斯霍恩spring-doc.cadn.net.cn

反应spring-doc.cadn.net.cn

纳斯霍恩spring-doc.cadn.net.cn

EJS公司spring-doc.cadn.net.cn

纳斯霍恩spring-doc.cadn.net.cn

ERB再培训局spring-doc.cadn.net.cn

JRubyspring-doc.cadn.net.cn

字符串模板spring-doc.cadn.net.cn

杰森spring-doc.cadn.net.cn

Kotlin 脚本模板spring-doc.cadn.net.cn

Kotlinspring-doc.cadn.net.cn

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

要求

您需要在类路径上安装脚本引擎,其详细信息因脚本引擎而异:spring-doc.cadn.net.cn

您需要有脚本模板库。对于 JavaScript 做到这一点的一种方法是 通过 WebJarsspring-doc.cadn.net.cn

脚本模板

您可以声明一个ScriptTemplateConfigurerbean 来指定要使用的脚本引擎, 要加载的脚本文件、要调用的函数来渲染模板等等。 以下示例使用 Mustache 模板和 Nashorn JavaScript 引擎:spring-doc.cadn.net.cn

@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函数使用以下参数调用:spring-doc.cadn.net.cn

Mustache.render()与此签名原生兼容,因此您可以直接调用它。spring-doc.cadn.net.cn

如果您的模板技术需要一些自定义,您可以提供一个脚本 实现自定义渲染函数。例如,Handlerbars 需要在使用模板之前编译模板,并且需要 polyfill 才能模拟一些模板 浏览器工具在服务器端脚本引擎中不可用。 以下示例演示如何设置自定义渲染函数:spring-doc.cadn.net.cn

@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
	}
}
设置sharedEngine属性设置为false使用非线程安全时是必需的 脚本引擎,其模板库不是为并发而设计的,例如 Handlebars 或 React 在 Nashorn 上运行。在这种情况下,由于此错误,需要 Java SE 8 更新 60,但通常是 在任何情况下都建议使用最新的 Java SE 补丁版本。

polyfill.js仅定义windowHandlebars 正常运行所需的对象, 如以下代码段所示:spring-doc.cadn.net.cn

var window = {};

这个基本的render.js实现在使用模板之前编译模板。A 制作 就绪实现还应存储和重用缓存模板或预编译模板。 这可以在脚本端完成,也可以在您需要的任何自定义(管理 模板引擎配置)。 以下示例显示了如何编译模板:spring-doc.cadn.net.cn

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

查看 Spring Framework 单元测试、Java资源, 了解更多配置示例。spring-doc.cadn.net.cn

HTML 片段

HTMXHotwire Turbo 强调 HTML-over-the-wire 方法,客户端以 HTML 而不是 JSON 形式接收服务器更新。 这允许 SPA(单页应用程序)的好处,而无需编写太多甚至 任何 JavaScript。如需了解详情,请访问各自的 网站。spring-doc.cadn.net.cn

在 Spring WebFlux 中,视图渲染通常涉及指定一个视图和一个模型。 但是,在 HTML-over-the-wire 中,一个常见的功能是发送多个 HTML 片段,这些 浏览器可用于更新页面的不同部分。为此,控制器方法 可以返回Collection<Fragment>.例如:spring-doc.cadn.net.cn

@GetMapping
List<Fragment> handle() {
	return List.of(Fragment.create("posts"), Fragment.create("comments"));
}
@GetMapping
fun handle(): List<Fragment> {
	return listOf(Fragment.create("posts"), Fragment.create("comments"))
}

同样也可以通过返回专用类型来完成FragmentsRendering:spring-doc.cadn.net.cn

@GetMapping
FragmentsRendering handle() {
	return FragmentsRendering.fragment("posts").fragment("comments").build();
}
@GetMapping
fun handle(): FragmentsRendering {
	return FragmentsRendering.fragment("posts").fragment("comments").build()
}

每个片段都可以有一个独立的模型,并且该模型继承了请求的属性shared 模型。spring-doc.cadn.net.cn

HTMX 和 Hotwire Turbo 支持通过 SSE 进行流式更新(服务器发送的事件)。控制器可以创建FragmentsRendering使用Flux<Fragment>,或与任何其他响应式生产者一起适应反应流Publisher通过ReactiveAdapterRegistry. 也可以退货Flux<Fragment>直接没有FragmentsRendering包装纸。spring-doc.cadn.net.cn

JSON 和 XML

出于内容协商的目的,能够在使用 HTML 模板或其他格式(例如 JSON 或 XML)之间交替渲染模型是很有用的,具体取决于客户端请求的内容类型。为了支持这样做,Spring WebFlux 提供了HttpMessageWriterView,您可以使用它来插入任何可用的编解码器spring-webJackson2JsonEncoder,Jackson2SmileEncoderJaxb2XmlEncoder.spring-doc.cadn.net.cn

与其他视图技术不同,HttpMessageWriterView不需要ViewResolver但是而是配置为默认视图。您可以配置一个或多个这样的默认视图,将不同的HttpMessageWriter实例 或Encoder实例。 与请求的内容类型匹配的在运行时使用。spring-doc.cadn.net.cn

在大多数情况下,一个模型包含多个属性。要确定要序列化哪一个,您可以配置HttpMessageWriterView替换为要用于的 Model 属性的名称 渲染。 如果模型仅包含一个属性,则使用该属性。spring-doc.cadn.net.cn