Spring WebFlux中视图技术的使用是可插入的,无论您决定使用Thymeleaf,Groovy标记模板,JSP还是其他技术,主要取决于配置更改。 本章介绍与Spring WebFlux集成的视图技术。 我们假设您已经熟悉View Resolution。
Thymeleaf是一种现代的服务器端Java模板引擎,它强调可以通过双击在浏览器中预览的自然HTML模板,这对于独立处理UI模板(例如,由设计人员)而无需使用非常有用。 正在运行的服务器。 如果要替换JSP,Thymeleaf提供了最广泛的功能集之一,以使这种过渡更加容易。 Thymeleaf是积极开发和维护的。 有关更完整的介绍,请参见Thymeleaf项目主页。
Thymeleaf与Spring MVC的集成由Thymeleaf项目管理。 该配置涉及一些Bean声明,例如ServletContextTemplateResolver,SpringTemplateEngine和ThymeleafViewResolver。 有关更多详细信息,请参见Thymeleaf + Spring。
Apache FreeMarker是一个模板引擎,用于生成从HTML到电子邮件等的任何类型的文本输出。 Spring框架具有内置的集成,可以将Spring MVC与FreeMarker模板一起使用。
View配置
以下示例显示如何将FreeMarker配置为一种视图技术:
@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("/WEB-INF/freemarker");
return configurer;
}
}
您的模板需要存储在上例所示的FreeMarkerConfigurer指定的目录中。 给定上述配置,如果您的控制器返回欢迎的视图名称,则解析器将查找/WEB-INF/freemarker/welcome.ftl模板。
FreeMarker Configuration
您可以通过在FreeMarkerConfigurer bean上设置适当的bean属性,将FreeMarker的“设置”和“ SharedVariables”直接传递给FreeMarker配置对象(由Spring管理)。 freemarkerSettings属性需要一个java.util.Properties对象,而freemarkerVariables属性需要一个java.util.Map。 以下示例显示了如何使用FreeMarkerConfigurer:
@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对象的详细信息,请参见FreeMarker文档。
Spring框架具有内置的集成,可以将Spring MVC与可以在JSR-223 Java脚本引擎之上运行的任何模板库一起使用。 我们已经在不同的脚本引擎上测试了以下模板库:
Scripting Library | Scripting Engine |
---|---|
Handlebars | Nashorn |
Mustache | Nashorn |
React | Nashorn |
EJS | Nashorn |
ERB | JRuby |
String templates | Jython |
Kotlin Script templating | Kotlin |
集成任何其他脚本引擎的基本规则是,它必须实现ScriptEngine和Invocable接口。
Requirements
您需要在类路径上具有脚本引擎,其细节因脚本引擎而异:
- Java 8+随附了Nashorn JavaScript引擎。 强烈建议使用可用的最新更新版本。
- 应该将JRuby添加为对Ruby支持的依赖。
- 应该将Jython添加为对Python支持的依赖项。
- 应该添加org.jetbrains.kotlin:kotlin-script-util依赖项和包含org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory行的META-INF / services / javax.script.ScriptEngineFactory文件。 有关更多详细信息,请参见此示例。
您需要具有脚本模板库。 针对Javascript的一种方法是通过WebJars。
Script Templates
您可以声明一个ScriptTemplateConfigurer bean来指定要使用的脚本引擎,要加载的脚本文件,调用呈现模板的函数等等。 以下示例使用Mustache模板和Nashorn JavaScript引擎:
@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;
}
}
使用以下参数调用render函数:
- String template:模板内容
- Map model:视图模型
- RenderingContext renderingContext:RenderingContext,用于访问应用程序上下文,语言环境,模板加载器和URL(自5.0起)
Mustache.render()与该签名本地兼容,因此您可以直接调用它。
如果您的模板技术需要一些自定义,则可以提供一个实现自定义渲染功能的脚本。 例如,Handlerbars需要在使用模板之前先对其进行编译,并且需要使用polyfill来模拟某些服务器端脚本引擎中不可用的浏览器功能。
以下示例显示了如何执行此操作:
@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;
}
}
当您将非线程安全脚本引擎与不是为并发设计的模板库一起使用时,例如,在Nashorn上运行的Handlebars或React,必须将sharedEngine属性设置为false。 在这种情况下,由于此错误,需要Java 8u60或更高版本。
polyfill.js仅定义Handlebars正常运行所需的window对象,如下所示:
var window = {};
这个基本的render.js实现在使用模板之前先对其进行编译。 生产就绪的实现还应该存储任何重用的缓存模板或预编译的模板。 您可以在脚本方面进行操作(并处理所需的任何自定义,例如管理模板引擎配置)。 以下示例显示了如何执行此操作:
function render(template, model) {
var compiledTemplate = Handlebars.compile(template);
return compiledTemplate(model);
}
出于内容协商的目的,根据客户端请求的内容类型,能够在使用HTML模板呈现模型或以其他格式(例如JSON或XML)呈现模型之间进行切换非常有用。为了支持此操作,Spring WebFlux提供了HttpMessageWriterView,您可以使用它插入spring-web中的任何可用编解码器,例如Jackson2JsonEncoder,Jackson2SmileEncoder或Jaxb2XmlEncoder。
与其他视图技术不同,HttpMessageWriterView不需要ViewResolver,而是配置为默认视图。您可以配置一个或多个此类默认视图,并包装不同的HttpMessageWriter实例或Encoder实例。在运行时使用与请求的内容类型匹配的内容。
在大多数情况下,模型包含多个属性。要确定要序列化的对象,可以使用模型属性的名称配置HttpMessageWriterView进行渲染。如果模型仅包含一个属性,则使用该属性。