[docs] View Technologies section in WebFlux
Issue: SPR-16393
This commit is contained in:
parent
49eec6248d
commit
5ff724968d
|
|
@ -0,0 +1,288 @@
|
|||
[[webflux-view]]
|
||||
= View Technologies
|
||||
[.small]#<<web.adoc#mvc-view,Same in Spring MVC>>#
|
||||
|
||||
The use of view technologies in Spring WebFlux is pluggable, whether you decide to
|
||||
use Thymeleaf, FreeMarker, or other, is primarily a matter of a configuration change.
|
||||
This chapter covers view technologies integrated with Spring WebFlux. We assume you are
|
||||
already familiar with <<webflux-viewresolution>>.
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-view-thymeleaf]]
|
||||
== Thymeleaf
|
||||
[.small]#<<web.adoc#mvc-view-thymeleaf,Same in Spring MVC>>#
|
||||
|
||||
Thymeleaf is modern server-side Java template engine that emphasizes natural HTML
|
||||
templates that can be previewed in a browser by double-clicking, which is very
|
||||
helpful for independent work on UI templates, e.g. by designer, without the need for a
|
||||
running server. Thymeleaf offers an extensive set of features and it is actively developed
|
||||
and maintained. For a more complete introduction see the
|
||||
http://www.thymeleaf.org/[Thymeleaf] project home page.
|
||||
|
||||
The Thymeleaf integration with Spring WebFlux is managed by the Thymeleaf project. The
|
||||
configuration involves a few bean declarations such as
|
||||
`SpringResourceTemplateResolver`, `SpringWebFluxTemplateEngine`, and
|
||||
`ThymeleafReactiveViewResolver`. For more details see
|
||||
http://www.thymeleaf.org/documentation.html[Thymeleaf+Spring] and the WebFlux integration
|
||||
http://forum.thymeleaf.org/Thymeleaf-3-0-8-JUST-PUBLISHED-td4030687.html[announcement].
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-view-freemarker]]
|
||||
== FreeMarker
|
||||
[.small]#<<web.adoc#mvc-view-freemarker,Same in Spring MVC>>#
|
||||
|
||||
http://www.freemarker.org[Apache FreeMarker] is a template engine for generating any
|
||||
kind of text output from HTML to email, and others. The Spring Framework has a built-in
|
||||
integration for using Spring WebFlux with FreeMarker templates.
|
||||
|
||||
|
||||
|
||||
[[webflux-view-freemarker-contextconfig]]
|
||||
=== View config
|
||||
[.small]#<<web.adoc#mvc-view-freemarker-contextconfig,Same in Spring MVC>>#
|
||||
|
||||
To configure FreeMarker as a view technology:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@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");
|
||||
return configurer;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Your templates need to be stored in the directory specified by the `FreeMarkerConfigurer`
|
||||
shown above. Given the above configuration if your controller returns the view name
|
||||
"welcome" then the resolver will look for the
|
||||
`classpath:/templates/freemarker/welcome.ftl` template.
|
||||
|
||||
|
||||
|
||||
[[webflux-views-freemarker]]
|
||||
=== FreeMarker config
|
||||
[.small]#<<web.adoc#mvc-views-freemarker,Same in Spring MVC>>#
|
||||
|
||||
FreeMarker 'Settings' and 'SharedVariables' can be passed directly to the FreeMarker
|
||||
`Configuration` object managed by Spring by setting the appropriate bean properties on
|
||||
the `FreeMarkerConfigurer` bean. The `freemarkerSettings` property requires a
|
||||
`java.util.Properties` object and the `freemarkerVariables` property requires a
|
||||
`java.util.Map`.
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@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;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
See the FreeMarker documentation for details of settings and variables as they apply to
|
||||
the `Configuration` object.
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-view-script]]
|
||||
== Script Views
|
||||
[.small]#<<web.adoc#mvc-view-script,Same in Spring MVC>>#
|
||||
|
||||
The Spring Framework has a built-in integration for using Spring WebFlux with any
|
||||
templating library that can run on top of the
|
||||
https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. Below is a list
|
||||
of templating libraries we've tested on different script engines:
|
||||
|
||||
[horizontal]
|
||||
http://handlebarsjs.com/[Handlebars] :: http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
https://mustache.github.io/[Mustache] :: http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
http://facebook.github.io/react/[React] :: http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
http://www.embeddedjs.com/[EJS] :: http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
http://www.stuartellis.eu/articles/erb/[ERB] :: http://jruby.org[JRuby]
|
||||
https://docs.python.org/2/library/string.html#template-strings[String templates] :: http://www.jython.org/[Jython]
|
||||
|
||||
[TIP]
|
||||
====
|
||||
The basic rule for integrating any other script engine is that it must implement the
|
||||
`ScriptEngine` and `Invocable` interfaces.
|
||||
====
|
||||
|
||||
|
||||
|
||||
[[webflux-view-script-dependencies]]
|
||||
=== Requirements
|
||||
[.small]#<<web.adoc#mvc-view-script-dependencies,Same in Spring MVC>>#
|
||||
|
||||
You need to have the script engine on your classpath:
|
||||
|
||||
* http://openjdk.java.net/projects/nashorn/[Nashorn] JavaScript engine is provided with
|
||||
Java 8+. Using the latest update release available is highly recommended.
|
||||
* http://jruby.org[JRuby] should be added as a dependency for Ruby support.
|
||||
* http://www.jython.org[Jython] should be added as a dependency for Python support.
|
||||
|
||||
You need to have the script templating library. One way to do that for Javascript is
|
||||
through http://www.webjars.org/[WebJars].
|
||||
|
||||
|
||||
|
||||
[[webflux-view-script-integrate]]
|
||||
=== Script templates
|
||||
[.small]#<<web.adoc#mvc-view-script-integrate,Same in Spring MVC>>#
|
||||
|
||||
Declare a `ScriptTemplateConfigurer` bean in order to specify the script engine to use,
|
||||
the script files to load, what function to call to render templates, and so on.
|
||||
Below is an example with Mustache templates and the Nashorn JavaScript engine:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@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;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The render function is called with the following parameters:
|
||||
|
||||
* `String template`: the template content
|
||||
* `Map model`: the view model
|
||||
* `String url`: the template url (since 4.2.2)
|
||||
|
||||
`Mustache.render()` is natively compatible with this signature, so you can call it directly.
|
||||
|
||||
If your templating technology requires some customization, you may provide a script that
|
||||
implements a custom render function. For example, http://handlebarsjs.com[Handlerbars]
|
||||
needs to compile templates before using them, and requires a
|
||||
http://en.wikipedia.org/wiki/Polyfill[polyfill] in order to emulate some
|
||||
browser facilities not available in the server-side script engine.
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
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;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Setting the `sharedEngine` property to `false` is required when using non thread-safe
|
||||
script engines with templating libraries not designed for concurrency, like Handlebars or
|
||||
React running on Nashorn for example. In that case, Java 8u60 or greater is required due
|
||||
to https://bugs.openjdk.java.net/browse/JDK-8076099[this bug].
|
||||
====
|
||||
|
||||
`polyfill.js` only defines the `window` object needed by Handlebars to run properly:
|
||||
|
||||
[source,javascript,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
var window = {};
|
||||
----
|
||||
|
||||
This basic `render.js` implementation compiles the template before using it. A production
|
||||
ready implementation should also store and reused cached templates / pre-compiled templates.
|
||||
This can be done on the script side, as well as any customization you need (managing
|
||||
template engine configuration for example).
|
||||
|
||||
[source,javascript,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
function render(template, model) {
|
||||
var compiledTemplate = Handlebars.compile(template);
|
||||
return compiledTemplate(model);
|
||||
}
|
||||
----
|
||||
|
||||
Check out the Spring Framework unit tests,
|
||||
https://github.com/spring-projects/spring-framework/tree/master/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[java], and
|
||||
https://github.com/spring-projects/spring-framework/tree/master/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],
|
||||
for more configuration examples.
|
||||
|
||||
|
||||
|
||||
[[webflux-view-httpmessagewriter]]
|
||||
== JSON, XML
|
||||
[.small]#<<web.adoc#mvc-view-jackson,Same in Spring MVC>>#
|
||||
|
||||
For <<webflux-multiple-representations>> purposes it is useful to be able to alternate
|
||||
between rendering a model with an HTML template or as other formats such as JSON or XML,
|
||||
depending on the content type requested by the client. To support this Spring WebFlux
|
||||
provides the `HttpMessageWriterView` that can be used to plug in any of the available
|
||||
<<webflux-codecs>> from `spring-web` such as `Jackson2JsonEncoder`,
|
||||
`Jackson2SmileEncoder`, or `Jaxb2XmlEncoder`.
|
||||
|
||||
Unlike other view technologies, `HttpMessageWriterView` does not require a `ViewResolver`,
|
||||
but instead is <<webflux-config-view-resolvers,configured>> as a default view. You can
|
||||
configure one more such default views, wrapping different ``HttpMessageWriter``'s or
|
||||
``Encoder``'s. The one that matches the requested content type is used at runtime.
|
||||
|
||||
In most cases a model will contain multiple attributes. In order to determine which one
|
||||
to serialize, `HttpMessageWriterView` can be configured with the name of the model
|
||||
attribute to use render, of if the model contains only one attribute, it will be used.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -729,6 +729,8 @@ To configure view resolution is as simple as adding a `ViewResolutionResultHandl
|
|||
to your Spring configuration. <<webflux-config-view-resolvers,WebFlux Config>> provides a
|
||||
dedicated configuration API for view resolution.
|
||||
|
||||
See <<webflux-view>> for more on the view technologies integrated with Spring WebFlux.
|
||||
|
||||
|
||||
[[webflux-redirecting-redirect-prefix]]
|
||||
==== Redirecting
|
||||
|
|
@ -2197,6 +2199,11 @@ reference documentation including:
|
|||
|
||||
|
||||
|
||||
include::webflux-view.adoc[leveloffset=+1]
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-config]]
|
||||
== WebFlux Config
|
||||
[.small]#<<web.adoc#mvc-config,Same in Spring MVC>>#
|
||||
|
|
@ -2494,6 +2501,8 @@ on the `HttpMessageWriterView` implementation which accepts any of the available
|
|||
}
|
||||
----
|
||||
|
||||
See <<webflux-view>> for more on the view technologies integrated with Spring WebFlux.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
[[mvc-view]]
|
||||
= View Technologies
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-view-introduction]]
|
||||
== Introduction
|
||||
[.small]#<<web-reactive.adoc#webflux-view,Same in Spring WebFlux>>#
|
||||
|
||||
The use of view technologies in Spring MVC is pluggable, whether you decide to
|
||||
use Thymeleaf, Groovy Markup Templates, JSPs, or other, is primarily a matter of a
|
||||
|
|
@ -17,6 +12,7 @@ We assume you are already familiar with <<mvc-viewresolver>>.
|
|||
|
||||
[[mvc-view-thymeleaf]]
|
||||
== Thymeleaf
|
||||
[.small]#<<web-reactive.adoc#webflux-view-thymeleaf,Same in Spring WebFlux>>#
|
||||
|
||||
Thymeleaf is modern server-side Java template engine that emphasizes natural HTML
|
||||
templates that can be previewed in a browser by double-clicking, which is very
|
||||
|
|
@ -36,6 +32,7 @@ See http://www.thymeleaf.org/documentation.html[Thymeleaf+Spring] for more detai
|
|||
|
||||
[[mvc-view-freemarker]]
|
||||
== FreeMarker
|
||||
[.small]#<<web-reactive.adoc#webflux-view-freemarker,Same in Spring WebFlux>>#
|
||||
|
||||
http://www.freemarker.org[Apache FreeMarker] is a template engine for generating any
|
||||
kind of text output from HTML to email, and others. The Spring Framework has a built-in
|
||||
|
|
@ -44,7 +41,8 @@ integration for using Spring MVC with FreeMarker templates.
|
|||
|
||||
|
||||
[[mvc-view-freemarker-contextconfig]]
|
||||
=== Context configuration
|
||||
=== View config
|
||||
[.small]#<<web-reactive.adoc#webflux-view-freemarker-contextconfig,Same in Spring WebFlux>>#
|
||||
|
||||
To configure FreeMarker as a view technology:
|
||||
|
||||
|
|
@ -99,19 +97,14 @@ properties:
|
|||
</bean>
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[mvc-view-freemarker-createtemplates]]
|
||||
=== Creating templates
|
||||
|
||||
Your templates need to be stored in the directory specified by the `FreeMarkerConfigurer`
|
||||
shown above. If you use the view resolvers highlighted, then the logical view names
|
||||
relate to the template file names. So if your controller returns the view name "welcome"
|
||||
then the resolver will look for the `/WEB-INF/freemarker/welcome.ftl` template.
|
||||
shown above. Given the above configuration if your controller returns the view name
|
||||
"welcome" then the resolver will look for the `/WEB-INF/freemarker/welcome.ftl` template.
|
||||
|
||||
|
||||
[[mvc-views-freemarker]]
|
||||
=== Advanced config
|
||||
=== FreeMarker config
|
||||
[.small]#<<web-reactive.adoc#webflux-views-freemarker,Same in Spring WebFlux>>#
|
||||
|
||||
FreeMarker 'Settings' and 'SharedVariables' can be passed directly to the FreeMarker
|
||||
`Configuration` object managed by Spring by setting the appropriate bean properties on
|
||||
|
|
@ -544,29 +537,32 @@ syntax. Here is a sample template for an HTML page:
|
|||
|
||||
[[mvc-view-script]]
|
||||
== Script Views
|
||||
[.small]#<<web-reactive.adoc#webflux-view-script,Same in Spring WebFlux>>#
|
||||
|
||||
The Spring Framework has a built-in integration for using Spring MVC with any
|
||||
templating library that can runs on top of the https://www.jcp
|
||||
.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. Below is a list of
|
||||
templating libraries we've tested on different script engines:
|
||||
templating library that can run on top of the
|
||||
https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. Below is a list
|
||||
of templating libraries we've tested on different script engines:
|
||||
|
||||
* http://handlebarsjs.com/[Handlebars] running on http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
* https://mustache.github.io/[Mustache] running on http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
* http://facebook.github.io/react/[React] running on http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
* http://www.embeddedjs.com/[EJS] running on http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
* http://www.stuartellis.eu/articles/erb/[ERB] running on http://jruby.org[JRuby]
|
||||
* https://docs.python.org/2/library/string.html#template-strings[String templates] running on http://www.jython.org/[Jython]
|
||||
[horizontal]
|
||||
http://handlebarsjs.com/[Handlebars] :: http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
https://mustache.github.io/[Mustache] :: http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
http://facebook.github.io/react/[React] :: http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
http://www.embeddedjs.com/[EJS] :: http://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
http://www.stuartellis.eu/articles/erb/[ERB] :: http://jruby.org[JRuby]
|
||||
https://docs.python.org/2/library/string.html#template-strings[String templates] :: http://www.jython.org/[Jython]
|
||||
|
||||
[TIP]
|
||||
====
|
||||
The basic rule for a script engine is that it must implement the `ScriptEngine` and
|
||||
`Invocable` interfaces.
|
||||
The basic rule for integrating any other script engine is that it must implement the
|
||||
`ScriptEngine` and `Invocable` interfaces.
|
||||
====
|
||||
|
||||
|
||||
|
||||
[[mvc-view-script-dependencies]]
|
||||
=== Requirements
|
||||
[.small]#<<web-reactive.adoc#webflux-view-script-dependencies,Same in Spring WebFlux>>#
|
||||
|
||||
You need to have the script engine on your classpath:
|
||||
|
||||
|
|
@ -582,21 +578,18 @@ through http://www.webjars.org/[WebJars].
|
|||
|
||||
[[mvc-view-script-integrate]]
|
||||
=== Script templates
|
||||
|
||||
To be able to use script templates, you have to configure it in order to specify various parameters
|
||||
like the script engine to use, the script files to load and what function should be called to
|
||||
render the templates. This is done thanks to a
|
||||
[.small]#<<web-reactive.adoc#webflux-script-integrate,Same in Spring WebFlux>>#
|
||||
|
||||
Declare a `ScriptTemplateConfigurer` bean in order to specify the script engine to use,
|
||||
the script files to load, what function to call to render templates, and so on.
|
||||
Below is an exmaple with Mustache templates and the Nashorn JavaScript engine:
|
||||
Below is an example with Mustache templates and the Nashorn JavaScript engine:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class MustacheConfig implements WebMvcConfigurer {
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureViewResolvers(ViewResolverRegistry registry) {
|
||||
|
|
@ -682,7 +675,7 @@ browser facilities not available in the server-side script engine.
|
|||
----
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class MustacheConfig implements WebMvcConfigurer {
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureViewResolvers(ViewResolverRegistry registry) {
|
||||
|
|
@ -731,9 +724,9 @@ template engine configuration for example).
|
|||
}
|
||||
----
|
||||
|
||||
Check out Spring script templates unit tests
|
||||
(https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[java],
|
||||
https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources])
|
||||
Check out the Spring Framework unit tests,
|
||||
https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[java], and
|
||||
https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],
|
||||
for more configuration examples.
|
||||
|
||||
|
||||
|
|
@ -2000,11 +1993,13 @@ document should appear listing each of the words in the model map.
|
|||
|
||||
[[mvc-view-jackson]]
|
||||
== Jackson
|
||||
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same in Spring WebFlux>>#
|
||||
|
||||
|
||||
|
||||
[[mvc-view-json-mapping]]
|
||||
=== JSON
|
||||
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same in Spring WebFlux>>#
|
||||
|
||||
The `MappingJackson2JsonView` uses the Jackson library's `ObjectMapper` to render the response
|
||||
content as JSON. By default, the entire contents of the model map (with the exception of
|
||||
|
|
@ -2027,6 +2022,7 @@ name(s) could be customized through the `jsonpParameterNames` property.
|
|||
|
||||
[[mvc-view-xml-mapping]]
|
||||
=== XML
|
||||
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same in Spring WebFlux>>#
|
||||
|
||||
The `MappingJackson2XmlView` uses the
|
||||
https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension]'s `XmlMapper`
|
||||
|
|
|
|||
Loading…
Reference in New Issue