diff --git a/src/docs/asciidoc/web/webmvc-view.adoc b/src/docs/asciidoc/web/webmvc-view.adoc
index 401e752348..193bc55381 100644
--- a/src/docs/asciidoc/web/webmvc-view.adoc
+++ b/src/docs/asciidoc/web/webmvc-view.adoc
@@ -34,90 +34,6 @@ See http://www.thymeleaf.org/documentation.html[Thymeleaf+Spring] for more detai
-[[mvc-view-groovymarkup]]
-== Groovy Markup
-
-http://groovy-lang.org/templating.html#_the_markuptemplateengine[Groovy Markup Template Engine]
-is primarily aimed at generating XML-like markup (XML, XHTML, HTML5, etc) but that can
-be used to generate any text based content. The Spring Framework has a built-in
-integration for using Spring MVC with Groovy Markup.
-
-[TIP]
-====
-The Groovy Markup Tempalte engine requires Groovy 2.3.1+.
-====
-
-
-
-[[mvc-view-groovymarkup-configuration]]
-=== Configuration
-
-To configure the Groovy Markup Template Engine:
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
- @Configuration
- @EnableWebMvc
- public class WebConfig implements WebMvcConfigurer {
-
- @Override
- public void configureViewResolvers(ViewResolverRegistry registry) {
- registry.groovy();
- }
-
- // Configure the Groovy Markup Template Engine...
-
- @Bean
- public GroovyMarkupConfigurer groovyMarkupConfigurer() {
- GroovyMarkupConfigurer configurer = new GroovyMarkupConfigurer();
- configurer.setResourceLoaderPath("/WEB-INF/");
- return configurer;
- }
- }
-----
-
-To configure the same in XML:
-
-[source,xml,indent=0]
-[subs="verbatim,quotes"]
-----
-
-
-
-
-
-
-
-
-----
-
-
-
-[[mvc-view-groovymarkup-example]]
-=== Example
-
-Unlike traditional template engines, Groovy Markup relies on a DSL that uses a builder
-syntax. Here is a sample template for an HTML page:
-
-[source,groovy,indent=0]
-[subs="verbatim,quotes"]
-----
- yieldUnescaped ''
- html(lang:'en') {
- head {
- meta('http-equiv':'"Content-Type" content="text/html; charset=utf-8"')
- title('My page')
- }
- body {
- p('This is an example of HTML contents')
- }
- }
-----
-
-
-
-
[[mvc-view-freemarker]]
== FreeMarker
@@ -542,131 +458,412 @@ In similar fashion, HTML escaping can be specified per field:
-[[mvc-view-jsp]]
-== JSP & JSTL
+[[mvc-view-groovymarkup]]
+== Groovy Markup
-The Spring Framework has a built-in integration for using Spring MVC with JSP and JSTL.
+http://groovy-lang.org/templating.html#_the_markuptemplateengine[Groovy Markup Template Engine]
+is primarily aimed at generating XML-like markup (XML, XHTML, HTML5, etc) but that can
+be used to generate any text based content. The Spring Framework has a built-in
+integration for using Spring MVC with Groovy Markup.
+[TIP]
+====
+The Groovy Markup Tempalte engine requires Groovy 2.3.1+.
+====
-[[mvc-view-jsp-resolver]]
-=== View resolvers
-When developing with JSPs you can declare a `InternalResourceViewResolver` or a
-`ResourceBundleViewResolver` bean.
+[[mvc-view-groovymarkup-configuration]]
+=== Configuration
-`ResourceBundleViewResolver` relies on a properties file to define the view names
-mapped to a class and a URL. With a `ResourceBundleViewResolver` you
-can mix different types of views using only one resolver. Here is an example:
+To configure the Groovy Markup Template Engine:
-[source,xml,indent=0]
+[source,java,indent=0]
[subs="verbatim,quotes"]
----
-
-
-
-
+ @Configuration
+ @EnableWebMvc
+ public class WebConfig implements WebMvcConfigurer {
- # And a sample properties file is uses (views.properties in WEB-INF/classes):
- welcome.(class)=org.springframework.web.servlet.view.JstlView
- welcome.url=/WEB-INF/jsp/welcome.jsp
+ @Override
+ public void configureViewResolvers(ViewResolverRegistry registry) {
+ registry.groovy();
+ }
- productList.(class)=org.springframework.web.servlet.view.JstlView
- productList.url=/WEB-INF/jsp/productlist.jsp
+ // Configure the Groovy Markup Template Engine...
+
+ @Bean
+ public GroovyMarkupConfigurer groovyMarkupConfigurer() {
+ GroovyMarkupConfigurer configurer = new GroovyMarkupConfigurer();
+ configurer.setResourceLoaderPath("/WEB-INF/");
+ return configurer;
+ }
+ }
----
-`InternalResourceBundleViewResolver` can also be used for JSPs. As a best practice, we
-strongly encourage placing your JSP files in a directory under the `'WEB-INF'`
-directory so there can be no direct access by clients.
+To configure the same in XML:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
-
-
-
-
-
-----
+
+
+
+
+
+
+----
-[[mvc-view-jsp-jstl]]
-=== JSPs versus JSTL
-When using the Java Standard Tag Library you must use a special view class, the
-`JstlView`, as JSTL needs some preparation before things such as the I18N features will
-work.
+[[mvc-view-groovymarkup-example]]
+=== Example
+Unlike traditional template engines, Groovy Markup relies on a DSL that uses a builder
+syntax. Here is a sample template for an HTML page:
-[[mvc-view-jsp-tags]]
-=== Spring's JSP tag library
+[source,groovy,indent=0]
+[subs="verbatim,quotes"]
+----
+ yieldUnescaped ''
+ html(lang:'en') {
+ head {
+ meta('http-equiv':'"Content-Type" content="text/html; charset=utf-8"')
+ title('My page')
+ }
+ body {
+ p('This is an example of HTML contents')
+ }
+ }
+----
-Spring provides data binding of request parameters to command objects as described in
-earlier chapters. To facilitate the development of JSP pages in combination with those
-data binding features, Spring provides a few tags that make things even easier. All
-Spring tags have__HTML escaping__ features to enable or disable escaping of characters.
-The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.
-For a comprehensive reference on individual tags, browse the
-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]
-or see the tag library description.
-[[mvc-view-jsp-formtaglib]]
-=== Spring's form tag library
+[[mvc-view-script]]
+== Script Views
-As of version 2.0, Spring provides a comprehensive set of data binding-aware tags for
-handling form elements when using JSP and Spring Web MVC. Each tag provides support for
-the set of attributes of its corresponding HTML tag counterpart, making the tags
-familiar and intuitive to use. The tag-generated HTML is HTML 4.01/XHTML 1.0 compliant.
+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:
-Unlike other form/input tag libraries, Spring's form tag library is integrated with
-Spring Web MVC, giving the tags access to the command object and reference data your
-controller deals with. As you will see in the following examples, the form tags make
-JSPs easier to develop, read and maintain.
+* 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]
-Let's go through the form tags and look at an example of how each tag is used. We have
-included generated HTML snippets where certain tags require further commentary.
+[TIP]
+====
+The basic rule for a script engine is that it must implement the `ScriptEngine` and
+`Invocable` interfaces.
+====
-[[mvc-view-jsp-formtaglib-configuration]]
-==== Configuration
-The form tag library comes bundled in `spring-webmvc.jar`. The library descriptor is
-called `spring-form.tld`.
+[[mvc-view-script-dependencies]]
+=== Requirements
-To use the tags from this library, add the following directive to the top of your JSP
-page:
+You need to have the script engine on your classpath:
-[source,xml,indent=0]
-[subs="verbatim,quotes"]
-----
- <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
-----
+* 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.
-where `form` is the tag name prefix you want to use for the tags from this library.
+You need to have the script templating library. One way to do that for Javascript is
+through http://www.webjars.org/[WebJars].
-[[mvc-view-jsp-formtaglib-formtag]]
-==== The form tag
-This tag renders an HTML 'form' tag and exposes a binding path to inner tags for
-binding. It puts the command object in the `PageContext` so that the command object can
-be accessed by inner tags. __All the other tags in this library are nested tags of the
-`form` tag__.
+[[mvc-view-script-integrate]]
+=== Script templates
-Let's assume we have a domain object called `User`. It is a JavaBean with properties
-such as `firstName` and `lastName`. We will use it as the form backing object of our
-form controller which returns `form.jsp`. Below is an example of what `form.jsp` would
-look like:
+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
-[source,xml,indent=0]
+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:
+
+[source,java,indent=0]
[subs="verbatim,quotes"]
----
-
-
+ @Configuration
+ @EnableWebMvc
+ public class MustacheConfig implements WebMvcConfigurer {
+
+ @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 same in XML:
+
+[source,xml,indent=0]
+[subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+----
+
+The controller would look no different:
+
+[source,java,indent=0]
+[subs="verbatim,quotes"]
+----
+ @Controller
+ public class SampleController {
+
+ @GetMapping("/sample")
+ public String test(Model model) {
+ model.addObject("title", "Sample title");
+ model.addObject("body", "Sample body");
+ return "template";
+ }
+ }
+----
+
+And the Mustache template is:
+
+[source,html,indent=0]
+[subs="verbatim,quotes"]
+----
+
+
+ {{title}}
+
+
+
{{body}}
+
+
+----
+
+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 MustacheConfig implements WebMvcConfigurer {
+
+ @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 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])
+for more configuration examples.
+
+
+
+
+[[mvc-view-jsp]]
+== JSP & JSTL
+
+The Spring Framework has a built-in integration for using Spring MVC with JSP and JSTL.
+
+
+
+[[mvc-view-jsp-resolver]]
+=== View resolvers
+
+When developing with JSPs you can declare a `InternalResourceViewResolver` or a
+`ResourceBundleViewResolver` bean.
+
+`ResourceBundleViewResolver` relies on a properties file to define the view names
+mapped to a class and a URL. With a `ResourceBundleViewResolver` you
+can mix different types of views using only one resolver. Here is an example:
+
+[source,xml,indent=0]
+[subs="verbatim,quotes"]
+----
+
+
+
+
+
+ # And a sample properties file is uses (views.properties in WEB-INF/classes):
+ welcome.(class)=org.springframework.web.servlet.view.JstlView
+ welcome.url=/WEB-INF/jsp/welcome.jsp
+
+ productList.(class)=org.springframework.web.servlet.view.JstlView
+ productList.url=/WEB-INF/jsp/productlist.jsp
+----
+
+`InternalResourceBundleViewResolver` can also be used for JSPs. As a best practice, we
+strongly encourage placing your JSP files in a directory under the `'WEB-INF'`
+directory so there can be no direct access by clients.
+
+[source,xml,indent=0]
+[subs="verbatim,quotes"]
+----
+
+
+
+
+
+----
+
+
+
+[[mvc-view-jsp-jstl]]
+=== JSPs versus JSTL
+
+When using the Java Standard Tag Library you must use a special view class, the
+`JstlView`, as JSTL needs some preparation before things such as the I18N features will
+work.
+
+
+
+[[mvc-view-jsp-tags]]
+=== Spring's JSP tag library
+
+Spring provides data binding of request parameters to command objects as described in
+earlier chapters. To facilitate the development of JSP pages in combination with those
+data binding features, Spring provides a few tags that make things even easier. All
+Spring tags have__HTML escaping__ features to enable or disable escaping of characters.
+
+The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.
+For a comprehensive reference on individual tags, browse the
+{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]
+or see the tag library description.
+
+
+[[mvc-view-jsp-formtaglib]]
+=== Spring's form tag library
+
+As of version 2.0, Spring provides a comprehensive set of data binding-aware tags for
+handling form elements when using JSP and Spring Web MVC. Each tag provides support for
+the set of attributes of its corresponding HTML tag counterpart, making the tags
+familiar and intuitive to use. The tag-generated HTML is HTML 4.01/XHTML 1.0 compliant.
+
+Unlike other form/input tag libraries, Spring's form tag library is integrated with
+Spring Web MVC, giving the tags access to the command object and reference data your
+controller deals with. As you will see in the following examples, the form tags make
+JSPs easier to develop, read and maintain.
+
+Let's go through the form tags and look at an example of how each tag is used. We have
+included generated HTML snippets where certain tags require further commentary.
+
+
+[[mvc-view-jsp-formtaglib-configuration]]
+==== Configuration
+
+The form tag library comes bundled in `spring-webmvc.jar`. The library descriptor is
+called `spring-form.tld`.
+
+To use the tags from this library, add the following directive to the top of your JSP
+page:
+
+[source,xml,indent=0]
+[subs="verbatim,quotes"]
+----
+ <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
+----
+
+where `form` is the tag name prefix you want to use for the tags from this library.
+
+
+[[mvc-view-jsp-formtaglib-formtag]]
+==== The form tag
+
+This tag renders an HTML 'form' tag and exposes a binding path to inner tags for
+binding. It puts the command object in the `PageContext` so that the command object can
+be accessed by inner tags. __All the other tags in this library are nested tags of the
+`form` tag__.
+
+Let's assume we have a domain object called `User`. It is a JavaBean with properties
+such as `firstName` and `lastName`. We will use it as the form backing object of our
+form controller which returns `form.jsp`. Below is an example of what `form.jsp` would
+look like:
+
+[source,xml,indent=0]
+[subs="verbatim,quotes"]
+----
+
+
First Name:
@@ -1295,294 +1492,83 @@ The HTML would look like:
----
-The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.
-For a comprehensive reference on individual tags, browse the
-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]
-or see the tag library description.
-
-
-[[mvc-rest-method-conversion]]
-==== HTTP method conversion
-
-A key principle of REST is the use of the Uniform Interface. This means that all
-resources (URLs) can be manipulated using the same four HTTP methods: GET, PUT, POST,
-and DELETE. For each method, the HTTP specification defines the exact semantics. For
-instance, a GET should always be a safe operation, meaning that is has no side effects,
-and a PUT or DELETE should be idempotent, meaning that you can repeat these operations
-over and over again, but the end result should be the same. While HTTP defines these
-four methods, HTML only supports two: GET and POST. Fortunately, there are two possible
-workarounds: you can either use JavaScript to do your PUT or DELETE, or simply do a POST
-with the 'real' method as an additional parameter (modeled as a hidden input field in an
-HTML form). This latter trick is what Spring's `HiddenHttpMethodFilter` does. This
-filter is a plain Servlet Filter and therefore it can be used in combination with any
-web framework (not just Spring MVC). Simply add this filter to your web.xml, and a POST
-with a hidden _method parameter will be converted into the corresponding HTTP method
-request.
-
-To support HTTP method conversion the Spring MVC form tag was updated to support setting
-the HTTP method. For example, the following snippet taken from the updated Petclinic
-sample
-
-[source,xml,indent=0]
-[subs="verbatim,quotes"]
-----
-
-
-
-----
-
-This will actually perform an HTTP POST, with the 'real' DELETE method hidden behind a
-request parameter, to be picked up by the `HiddenHttpMethodFilter`, as defined in
-web.xml:
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
-
- httpMethodFilter
- org.springframework.web.filter.HiddenHttpMethodFilter
-
-
-
- httpMethodFilter
- petclinic
-
-----
-
-The corresponding `@Controller` method is shown below:
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
- @RequestMapping(method = RequestMethod.DELETE)
- public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
- this.clinic.deletePet(petId);
- return "redirect:/owners/" + ownerId;
- }
-----
-
-
-[[mvc-view-jsp-formtaglib-html5]]
-==== HTML5 tags
-
-Starting with Spring 3, the Spring form tag library allows entering dynamic attributes,
-which means you can enter any HTML5 specific attributes.
-
-In Spring 3.1, the form input tag supports entering a type attribute other than 'text'.
-This is intended to allow rendering new HTML5 specific input types such as 'email',
-'date', 'range', and others. Note that entering type='text' is not required since 'text'
-is the default type.
-
-
-
-
-[[mvc-view-script]]
-== Script views
-
-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:
-
-* 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]
-
-[TIP]
-====
-The basic rule for a script engine is that it must implement the `ScriptEngine` and
-`Invocable` interfaces.
-====
-
-
-
-[[mvc-view-script-dependencies]]
-=== Requirements
-
-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].
-
-
-
-[[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
-
-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:
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
- @Configuration
- @EnableWebMvc
- public class MustacheConfig implements WebMvcConfigurer {
-
- @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 same in XML:
-
-[source,xml,indent=0]
-[subs="verbatim,quotes"]
-----
-
-
-
-
-
-
-
-
-
-----
-
-The controller would look no different:
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
- @Controller
- public class SampleController {
-
- @GetMapping("/sample")
- public String test(Model model) {
- model.addObject("title", "Sample title");
- model.addObject("body", "Sample body");
- return "template";
- }
- }
-----
-
-And the Mustache template is:
-
-[source,html,indent=0]
-[subs="verbatim,quotes"]
-----
-
-
- {{title}}
-
-
-
{{body}}
-
-
-----
-
-The render function is called with the following parameters:
+The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.
+For a comprehensive reference on individual tags, browse the
+{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]
+or see the tag library description.
-* `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.
+[[mvc-rest-method-conversion]]
+==== HTTP method conversion
-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.
+A key principle of REST is the use of the Uniform Interface. This means that all
+resources (URLs) can be manipulated using the same four HTTP methods: GET, PUT, POST,
+and DELETE. For each method, the HTTP specification defines the exact semantics. For
+instance, a GET should always be a safe operation, meaning that is has no side effects,
+and a PUT or DELETE should be idempotent, meaning that you can repeat these operations
+over and over again, but the end result should be the same. While HTTP defines these
+four methods, HTML only supports two: GET and POST. Fortunately, there are two possible
+workarounds: you can either use JavaScript to do your PUT or DELETE, or simply do a POST
+with the 'real' method as an additional parameter (modeled as a hidden input field in an
+HTML form). This latter trick is what Spring's `HiddenHttpMethodFilter` does. This
+filter is a plain Servlet Filter and therefore it can be used in combination with any
+web framework (not just Spring MVC). Simply add this filter to your web.xml, and a POST
+with a hidden _method parameter will be converted into the corresponding HTTP method
+request.
-[source,java,indent=0]
+To support HTTP method conversion the Spring MVC form tag was updated to support setting
+the HTTP method. For example, the following snippet taken from the updated Petclinic
+sample
+
+[source,xml,indent=0]
[subs="verbatim,quotes"]
----
- @Configuration
- @EnableWebMvc
- public class MustacheConfig implements WebMvcConfigurer {
-
- @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:
+This will actually perform an HTTP POST, with the 'real' DELETE method hidden behind a
+request parameter, to be picked up by the `HiddenHttpMethodFilter`, as defined in
+web.xml:
-[source,javascript,indent=0]
+[source,java,indent=0]
[subs="verbatim,quotes"]
----
- var window = {};
+
+ httpMethodFilter
+ org.springframework.web.filter.HiddenHttpMethodFilter
+
+
+
+ httpMethodFilter
+ petclinic
+
----
-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).
+The corresponding `@Controller` method is shown below:
-[source,javascript,indent=0]
+[source,java,indent=0]
[subs="verbatim,quotes"]
----
- function render(template, model) {
- var compiledTemplate = Handlebars.compile(template);
- return compiledTemplate(model);
+ @RequestMapping(method = RequestMethod.DELETE)
+ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
+ this.clinic.deletePet(petId);
+ return "redirect:/owners/" + ownerId;
}
----
-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])
-for more configuration examples.
-
-
+[[mvc-view-jsp-formtaglib-html5]]
+==== HTML5 tags
-[[mvc-view-xml-marshalling]]
-== XML Marshalling
+Starting with Spring 3, the Spring form tag library allows entering dynamic attributes,
+which means you can enter any HTML5 specific attributes.
-The `MarshallingView` uses an XML `Marshaller` defined in the `org.springframework.oxm`
-package to render the response content as XML. The object to be marshalled can be set
-explicitly using ``MarhsallingView``'s `modelKey` bean property. Alternatively, the view
-will iterate over all model properties and marshal the first type that is supported
-by the `Marshaller`. For more information on the functionality in the
-`org.springframework.oxm` package refer to the chapter <>.
+In Spring 3.1, the form input tag supports entering a type attribute other than 'text'.
+This is intended to allow rendering new HTML5 specific input types such as 'email',
+'date', 'range', and others. Note that entering type='text' is not required since 'text'
+is the default type.
@@ -1764,161 +1750,73 @@ per preparer name (as used in your Tiles definitions).
-[[mvc-view-xslt]]
-== XSLT
-
-XSLT is a transformation language for XML and is popular as a view technology within web
-applications. XSLT can be a good choice as a view technology if your application
-naturally deals with XML, or if your model can easily be converted to XML. The following
-section shows how to produce an XML document as model data and have it transformed with
-XSLT in a Spring Web MVC application.
-
-This example is a trivial Spring application that creates a list of words in the
-`Controller` and adds them to the model map. The map is returned along with the view
-name of our XSLT view. See <> for details of Spring Web MVC's
-`Controller` interface. The XSLT Controller will turn the list of words into a simple XML
-document ready for transformation.
-
-
-
-[[mvc-view-xslt-beandefs]]
-=== Beans
-
-Configuration is standard for a simple Spring application.
-The MVC configuration has to define a `XsltViewResolver` bean and
-regular MVC annotation configuration.
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
-@EnableWebMvc
-@ComponentScan
-@Configuration
-public class WebConfig implements WebMvcConfigurer {
-
- @Bean
- public XsltViewResolver xsltViewResolver() {
- XsltViewResolver viewResolver = new XsltViewResolver();
- viewResolver.setPrefix("/WEB-INF/xsl/");
- viewResolver.setSuffix(".xslt");
- return viewResolver;
- }
-
-}
-----
-
-And we need a Controller that encapsulates our word generation logic.
-
-
+[[mvc-view-feeds]]
+== RSS, Atom
-[[mvc-view-xslt-controllercode]]
-=== Controller
+Both `AbstractAtomFeedView` and `AbstractRssFeedView` inherit from the base class
+`AbstractFeedView` and are used to provide Atom and RSS Feed views respectfully. They
+are based on java.net's https://rome.dev.java.net[ROME] project and are located in the
+package `org.springframework.web.servlet.view.feed`.
-The controller logic is encapsulated in a `@Controller` class, with the
-handler method being defined like so...
+`AbstractAtomFeedView` requires you to implement the `buildFeedEntries()` method and
+optionally override the `buildFeedMetadata()` method (the default implementation is
+empty), as shown below.
[source,java,indent=0]
[subs="verbatim,quotes"]
----
- @Controller
- public class XsltController {
-
- @RequestMapping("/")
- public String home(Model model) throws Exception {
-
- Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
- Element root = document.createElement("wordList");
+ public class SampleContentAtomView extends AbstractAtomFeedView {
- List words = Arrays.asList("Hello", "Spring", "Framework");
- for (String word : words) {
- Element wordNode = document.createElement("word");
- Text textNode = document.createTextNode(word);
- wordNode.appendChild(textNode);
- root.appendChild(wordNode);
- }
+ @Override
+ protected void buildFeedMetadata(Map model,
+ Feed feed, HttpServletRequest request) {
+ // implementation omitted
+ }
- model.addAttribute("wordList", root);
- return "home";
+ @Override
+ protected List buildFeedEntries(Map model,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // implementation omitted
}
}
----
-So far we've only created a DOM document and added it to the Model map. Note that you
-can also load an XML file as a `Resource` and use it instead of a custom DOM document.
-
-Of course, there are software packages available that will automatically 'domify'
-an object graph, but within Spring, you have complete flexibility to create the DOM
-from your model in any way you choose. This prevents the transformation of XML playing
-too great a part in the structure of your model data which is a danger when using tools
-to manage the domification process.
-
-Next, `XsltViewResolver` will resolve the "home" XSLT template file and merge the
-DOM document into it to generate our view.
-
-
-
-[[mvc-view-xslt-transforming]]
-=== Transformation
-
-Finally, the `XsltViewResolver` will resolve the "home" XSLT template file and merge the
-DOM document into it to generate our view. As shown in the `XsltViewResolver`
-configuration, XSLT templates live in the war file in the `'WEB-INF/xsl'` directory
-and end with a `"xslt"` file extension.
+Similar requirements apply for implementing `AbstractRssFeedView`, as shown below.
-[source,xml,indent=0]
+[source,java,indent=0]
[subs="verbatim,quotes"]
----
-
-
-
-
+ public class SampleContentAtomView extends AbstractRssFeedView {
-
-
- Hello!
-
-
-
+ @Override
+ protected List buildFeedItems(Map model,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // implementation omitted
+ }
-
+ }
----
-This is rendered as:
+The `buildFeedItems()` and `buildFeedEntires()` methods pass in the HTTP request in case
+you need to access the Locale. The HTTP response is passed in only for the setting of
+cookies or other HTTP headers. The feed will automatically be written to the response
+object after the method returns.
-[source,html,indent=0]
-[subs="verbatim,quotes"]
-----
-
-
-
- Hello!
-
-
-
My First Words
-
-
Hello
-
Spring
-
Framework
-
-
-
-----
+For an example of creating an Atom view please refer to Alef Arendsen's Spring Team Blog
+https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].
[[mvc-view-document]]
-== Document views: PDF, Excel
+== PDF, Excel
@@ -2100,71 +1998,6 @@ document should appear listing each of the words in the model map.
-[[mvc-view-feeds]]
-== Feed views: RSS, Atom
-
-Both `AbstractAtomFeedView` and `AbstractRssFeedView` inherit from the base class
-`AbstractFeedView` and are used to provide Atom and RSS Feed views respectfully. They
-are based on java.net's https://rome.dev.java.net[ROME] project and are located in the
-package `org.springframework.web.servlet.view.feed`.
-
-`AbstractAtomFeedView` requires you to implement the `buildFeedEntries()` method and
-optionally override the `buildFeedMetadata()` method (the default implementation is
-empty), as shown below.
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
- public class SampleContentAtomView extends AbstractAtomFeedView {
-
- @Override
- protected void buildFeedMetadata(Map model,
- Feed feed, HttpServletRequest request) {
- // implementation omitted
- }
-
- @Override
- protected List buildFeedEntries(Map model,
- HttpServletRequest request, HttpServletResponse response) throws Exception {
- // implementation omitted
- }
-
- }
-----
-
-Similar requirements apply for implementing `AbstractRssFeedView`, as shown below.
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
- public class SampleContentAtomView extends AbstractRssFeedView {
-
- @Override
- protected void buildFeedMetadata(Map model,
- Channel feed, HttpServletRequest request) {
- // implementation omitted
- }
-
- @Override
- protected List buildFeedItems(Map model,
- HttpServletRequest request, HttpServletResponse response) throws Exception {
- // implementation omitted
- }
-
- }
-----
-
-The `buildFeedItems()` and `buildFeedEntires()` methods pass in the HTTP request in case
-you need to access the Locale. The HTTP response is passed in only for the setting of
-cookies or other HTTP headers. The feed will automatically be written to the response
-object after the method returns.
-
-For an example of creating an Atom view please refer to Alef Arendsen's Spring Team Blog
-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].
-
-
-
-
[[mvc-view-jackson]]
== Jackson
@@ -2205,3 +2038,170 @@ XML mapping can be customized as needed through the use of JAXB or Jackson's pro
annotations. When further control is needed, a custom `XmlMapper` can be injected
through the `ObjectMapper` property for cases where custom XML
serializers/deserializers need to be provided for specific types.
+
+
+
+
+[[mvc-view-xml-marshalling]]
+== XML
+
+The `MarshallingView` uses an XML `Marshaller` defined in the `org.springframework.oxm`
+package to render the response content as XML. The object to be marshalled can be set
+explicitly using ``MarhsallingView``'s `modelKey` bean property. Alternatively, the view
+will iterate over all model properties and marshal the first type that is supported
+by the `Marshaller`. For more information on the functionality in the
+`org.springframework.oxm` package refer to the chapter <>.
+
+
+
+
+[[mvc-view-xslt]]
+== XSLT
+
+XSLT is a transformation language for XML and is popular as a view technology within web
+applications. XSLT can be a good choice as a view technology if your application
+naturally deals with XML, or if your model can easily be converted to XML. The following
+section shows how to produce an XML document as model data and have it transformed with
+XSLT in a Spring Web MVC application.
+
+This example is a trivial Spring application that creates a list of words in the
+`Controller` and adds them to the model map. The map is returned along with the view
+name of our XSLT view. See <> for details of Spring Web MVC's
+`Controller` interface. The XSLT Controller will turn the list of words into a simple XML
+document ready for transformation.
+
+
+
+[[mvc-view-xslt-beandefs]]
+=== Beans
+
+Configuration is standard for a simple Spring application.
+The MVC configuration has to define a `XsltViewResolver` bean and
+regular MVC annotation configuration.
+
+[source,java,indent=0]
+[subs="verbatim,quotes"]
+----
+@EnableWebMvc
+@ComponentScan
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+ @Bean
+ public XsltViewResolver xsltViewResolver() {
+ XsltViewResolver viewResolver = new XsltViewResolver();
+ viewResolver.setPrefix("/WEB-INF/xsl/");
+ viewResolver.setSuffix(".xslt");
+ return viewResolver;
+ }
+
+}
+----
+
+And we need a Controller that encapsulates our word generation logic.
+
+
+
+[[mvc-view-xslt-controllercode]]
+=== Controller
+
+The controller logic is encapsulated in a `@Controller` class, with the
+handler method being defined like so...
+
+[source,java,indent=0]
+[subs="verbatim,quotes"]
+----
+ @Controller
+ public class XsltController {
+
+ @RequestMapping("/")
+ public String home(Model model) throws Exception {
+
+ Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ Element root = document.createElement("wordList");
+
+ List words = Arrays.asList("Hello", "Spring", "Framework");
+ for (String word : words) {
+ Element wordNode = document.createElement("word");
+ Text textNode = document.createTextNode(word);
+ wordNode.appendChild(textNode);
+ root.appendChild(wordNode);
+ }
+
+ model.addAttribute("wordList", root);
+ return "home";
+ }
+
+ }
+----
+
+So far we've only created a DOM document and added it to the Model map. Note that you
+can also load an XML file as a `Resource` and use it instead of a custom DOM document.
+
+Of course, there are software packages available that will automatically 'domify'
+an object graph, but within Spring, you have complete flexibility to create the DOM
+from your model in any way you choose. This prevents the transformation of XML playing
+too great a part in the structure of your model data which is a danger when using tools
+to manage the domification process.
+
+Next, `XsltViewResolver` will resolve the "home" XSLT template file and merge the
+DOM document into it to generate our view.
+
+
+
+[[mvc-view-xslt-transforming]]
+=== Transformation
+
+Finally, the `XsltViewResolver` will resolve the "home" XSLT template file and merge the
+DOM document into it to generate our view. As shown in the `XsltViewResolver`
+configuration, XSLT templates live in the war file in the `'WEB-INF/xsl'` directory
+and end with a `"xslt"` file extension.
+
+[source,xml,indent=0]
+[subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+ Hello!
+
+