DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(baseUrl);
@ -117,6 +182,16 @@ that holds configuration and preferences, as the following example shows:
@@ -117,6 +182,16 @@ that holds configuration and preferences, as the following example shows:
URI uri = UriComponentsBuilder.fromPath("/hotel list/{city}")
URI uri = UriComponentsBuilder.fromPath("/hotel list/{city}")
.queryParam("q", "{q}")
.encode()
.buildAndExpand("New York", "foo+bar")
@ -155,24 +230,48 @@ URI uri = UriComponentsBuilder.fromPath("/hotel list/{city}")
@@ -155,24 +230,48 @@ URI uri = UriComponentsBuilder.fromPath("/hotel list/{city}")
// Result is "/hotel%20list/New%20York?q=foo%2Bbar"
val uri = UriComponentsBuilder.fromPath("/hotel list/{city}?q={q}")
.build("New York", "foo+bar")
----
@ -180,8 +279,8 @@ The `WebClient` and the `RestTemplate` expand and encode URI templates internall
@@ -180,8 +279,8 @@ The `WebClient` and the `RestTemplate` expand and encode URI templates internall
the `UriBuilderFactory` strategy. Both can be configured with a custom strategy.
@ -46,33 +46,51 @@ integration for using Spring MVC with FreeMarker templates.
@@ -46,33 +46,51 @@ integration for using Spring MVC with FreeMarker templates.
The following example shows how to configure FreeMarker as a view technology:
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("/WEB-INF/freemarker")
}
}
----
The following example shows how to configure the same in XML:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<mvc:annotation-driven/>
@ -89,8 +107,7 @@ The following example shows how to configure the same in XML:
@@ -89,8 +107,7 @@ The following example shows how to configure the same in XML:
Alternatively, you can also declare the `FreeMarkerConfigurer` bean for full control over all
@ -114,8 +131,7 @@ properties on the `FreeMarkerConfigurer` bean. The `freemarkerSettings` property
@@ -114,8 +131,7 @@ properties on the `FreeMarkerConfigurer` bean. The `freemarkerSettings` property
a `java.util.Properties` object, and the `freemarkerVariables` property requires a
`java.util.Map`. The following example shows how to use a `FreeMarkerConfigurer`:
@ -167,8 +183,7 @@ controller, you can use code similar to the next example to bind to field values
@@ -167,8 +183,7 @@ controller, you can use code similar to the next example to bind to field values
display error messages for each input field in similar fashion to the JSP equivalent. The
following example shows a `personForm` view:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<!-- FreeMarker macros have to be imported into a namespace.
We strongly recommend sticking to 'spring'. -->
@ -309,8 +324,7 @@ time, a class name or style attribute. Note that FreeMarker can specify default
@@ -309,8 +324,7 @@ time, a class name or style attribute. Note that FreeMarker can specify default
values for the attributes parameter. The following example shows how to use the `formInput`
and `showWErrors` macros:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<@spring.formInput "command.name"/>
<@spring.showErrors "<br>"/>
@ -322,8 +336,7 @@ occurs through Spring's Validation framework.
@@ -322,8 +336,7 @@ occurs through Spring's Validation framework.
The generated HTML resembles the following example:
[source,jsp,indent=0]
[subs="verbatim,quotes"]
[source,jsp,indent=0,subs="verbatim,quotes"]
----
Name:
<input type="text" name="name" value="">
@ -357,8 +370,7 @@ value of 'London' for this field, so no validation is necessary. When the form i
@@ -357,8 +370,7 @@ value of 'London' for this field, so no validation is necessary. When the form i
rendered, the entire list of cities to choose from is supplied as reference data in the
model under the name 'cityMap'. The following listing shows the example:
[source,jsp,indent=0]
[subs="verbatim,quotes"]
[source,jsp,indent=0,subs="verbatim,quotes"]
----
...
Town:
@ -372,8 +384,7 @@ keys are what the form actually submits as `POST` request parameters. The map va
@@ -372,8 +384,7 @@ keys are what the form actually submits as `POST` request parameters. The map va
labels that the user sees. In the preceding example, given a list of three well known cities
and a default value in the form backing object, the HTML resembles the following:
@ -384,26 +395,37 @@ and a default value in the form backing object, the HTML resembles the following
@@ -384,26 +395,37 @@ and a default value in the form backing object, the HTML resembles the following
If your application expects to handle cities by internal codes (for example), you can create the map of
codes with suitable keys, as the following example shows:
@ -426,8 +448,7 @@ template processing to provide different behavior for different fields in your f
@@ -426,8 +448,7 @@ template processing to provide different behavior for different fields in your f
To switch to XHTML compliance for your tags, specify a value of `true` for a
model or context variable named `xhtmlCompliant`, as the following example shows:
@ -493,11 +513,29 @@ The following example shows how to configure the Groovy Markup Template Engine:
@@ -493,11 +513,29 @@ The following example shows how to configure the Groovy Markup Template Engine:
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.groovy()
}
// Configure the Groovy Markup Template Engine...
@Bean
fun groovyMarkupConfigurer() = GroovyMarkupConfigurer().apply {
resourceLoaderPath = "/WEB-INF/"
}
}
----
The following example shows how to configure the same in XML:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<mvc:annotation-driven/>
@ -517,8 +555,7 @@ The following example shows how to configure the same in XML:
@@ -517,8 +555,7 @@ The following example shows how to configure the same in XML:
Unlike traditional template engines, Groovy Markup relies on a DSL that uses a builder
syntax. The following example shows a sample template for an HTML page:
[source,groovy,indent=0]
[subs="verbatim,quotes"]
[source,groovy,indent=0,subs="verbatim,quotes"]
----
yieldUnescaped '<!DOCTYPE html>'
html(lang:'en') {
@ -589,8 +626,8 @@ You can declare a `ScriptTemplateConfigurer` bean to specify the script engine t
@@ -589,8 +626,8 @@ You can declare a `ScriptTemplateConfigurer` bean to specify the script engine t
the script files to load, what function to call to render templates, and so on.
The following example uses Mustache templates and the Nashorn JavaScript engine:
@ -612,11 +649,30 @@ The following example uses Mustache templates and the Nashorn JavaScript engine:
@@ -612,11 +649,30 @@ The following example uses Mustache templates and the Nashorn JavaScript engine:
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.scriptTemplate()
}
@Bean
fun configurer() = ScriptTemplateConfigurer().apply {
engineName = "nashorn"
setScripts("mustache.js")
renderObject = "Mustache"
renderFunction = "render"
}
}
----
The following example shows the same arrangement in XML:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<mvc:annotation-driven/>
@ -631,25 +687,38 @@ The following example shows the same arrangement in XML:
@@ -631,25 +687,38 @@ The following example shows the same arrangement in XML:
The controller would look no different for the Java and XML configurations, as the following example shows:
The following example shows the Mustache template:
[source,html,indent=0]
[subs="verbatim,quotes"]
[source,html,indent=0,subs="verbatim,quotes"]
----
<html>
<head>
@ -680,8 +749,8 @@ browser facilities that are not available in the server-side script engine.
@@ -680,8 +749,8 @@ browser facilities that are not available in the server-side script engine.
@ -722,8 +810,7 @@ implementation should also store any reused cached templates or pre-compiled tem
@@ -722,8 +810,7 @@ implementation should also store any reused cached templates or pre-compiled tem
You can do so on the script side (and handle any customization you need -- managing
template engine configuration, for example). The following example shows how to do so:
var compiledTemplate = Handlebars.compile(template);
@ -756,8 +843,7 @@ When developing with JSPs, you can declare a `InternalResourceViewResolver` or a
@@ -756,8 +843,7 @@ When developing with JSPs, you can declare a `InternalResourceViewResolver` or a
mapped to a class and a URL. With a `ResourceBundleViewResolver`, you can mix
different types of views by using only one resolver, as the following example shows:
@ -776,8 +862,7 @@ different types of views by using only one resolver, as the following example sh
@@ -776,8 +862,7 @@ different types of views by using only one resolver, as the following example sh
encourage placing your JSP files in a directory under the `'WEB-INF'` directory so there
@ -858,8 +943,7 @@ such as `firstName` and `lastName`. We can use it as the form-backing object of
@@ -858,8 +943,7 @@ such as `firstName` and `lastName`. We can use it as the form-backing object of
form controller, which returns `form.jsp`. The following example shows what `form.jsp` could
look like:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form:form>
<table>
@ -886,8 +970,7 @@ how inner tags are used with the `form` tag.
@@ -886,8 +970,7 @@ how inner tags are used with the `form` tag.
The following listing shows the generated HTML, which looks like a standard form:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form method="POST">
<table>
@ -913,8 +996,7 @@ The preceding JSP assumes that the variable name of the form-backing object is
@@ -913,8 +996,7 @@ The preceding JSP assumes that the variable name of the form-backing object is
(definitely a best practice), you can bind the form to the named variable, as the
following example shows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form:form modelAttribute="user">
<table>
@ -952,8 +1034,8 @@ This tag renders an HTML `input` tag with the `type` set to `checkbox`.
@@ -952,8 +1034,8 @@ This tag renders an HTML `input` tag with the `type` set to `checkbox`.
Assume that our `User` has preferences such as newsletter subscription and a list of
hobbies. The following example shows the `Preferences` class:
@ -986,11 +1068,19 @@ hobbies. The following example shows the `Preferences` class:
@@ -986,11 +1068,19 @@ hobbies. The following example shows the `Preferences` class:
The corresponding `form.jsp` could then resemble the following:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form:form>
<table>
@ -1035,8 +1125,7 @@ There are three approaches to the `checkbox` tag, which should meet all your che
@@ -1035,8 +1125,7 @@ There are three approaches to the `checkbox` tag, which should meet all your che
Note that, regardless of the approach, the same HTML structure is generated. The following
HTML snippet defines some checkboxes:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Interests:</td>
@ -1074,8 +1163,7 @@ the available options in the `items` property. Typically, the bound property is
@@ -1074,8 +1163,7 @@ the available options in the `items` property. Typically, the bound property is
collection so that it can hold multiple values selected by the user. The following example
shows a JSP that uses this tag:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form:form>
<table>
@ -1106,8 +1194,7 @@ This tag renders an HTML `input` element with the `type` set to `radio`.
@@ -1106,8 +1194,7 @@ This tag renders an HTML `input` element with the `type` set to `radio`.
A typical usage pattern involves multiple tag instances bound to the same property
but with different values, as the following example shows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Sex:</td>
@ -1132,8 +1219,7 @@ used as the value and the map entry's value are used as the label to be displaye
@@ -1132,8 +1219,7 @@ used as the value and the map entry's value are used as the label to be displaye
You can also use a custom object where you can provide the property names for the value
by using `itemValue` and the label by using `itemLabel`, as the following example shows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Sex:</td>
@ -1147,8 +1233,7 @@ by using `itemValue` and the label by using `itemLabel`, as the following exampl
@@ -1147,8 +1233,7 @@ by using `itemValue` and the label by using `itemLabel`, as the following exampl
This tag renders an HTML `input` tag with the type set to `password` with the bound value.
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Password:</td>
@ -1162,8 +1247,7 @@ Note that, by default, the password value is not shown. If you do want the
@@ -1162,8 +1247,7 @@ Note that, by default, the password value is not shown. If you do want the
password value to be shown, you can set the value of the `showPassword` attribute to
`true`, as the following example shows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Password:</td>
@ -1182,8 +1266,7 @@ option as well as the use of nested `option` and `options` tags.
@@ -1182,8 +1266,7 @@ option as well as the use of nested `option` and `options` tags.
Assume that a `User` has a list of skills. The corresponding HTML could be as follows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Skills:</td>
@ -1194,8 +1277,7 @@ Assume that a `User` has a list of skills. The corresponding HTML could be as fo
@@ -1194,8 +1277,7 @@ Assume that a `User` has a list of skills. The corresponding HTML could be as fo
If the `User's` skill are in Herbology, the HTML source of the 'Skills' row could be
as follows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Skills:</td>
@ -1216,8 +1298,7 @@ as follows:
@@ -1216,8 +1298,7 @@ as follows:
This tag renders an HTML `option` element. It sets `selected`, based on the bound
value. The following HTML shows typical output for it:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>House:</td>
@ -1235,8 +1316,7 @@ value. The following HTML shows typical output for it:
@@ -1235,8 +1316,7 @@ value. The following HTML shows typical output for it:
If the `User's` house was in Gryffindor, the HTML source of the 'House' row would be
as follows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>House:</td>
@ -1259,8 +1339,7 @@ as follows:
@@ -1259,8 +1339,7 @@ as follows:
This tag renders a list of HTML `option` elements. It sets the `selected` attribute,
based on the bound value. The following HTML shows typical output for it:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Country:</td>
@ -1275,8 +1354,7 @@ based on the bound value. The following HTML shows typical output for it:
@@ -1275,8 +1354,7 @@ based on the bound value. The following HTML shows typical output for it:
If the `User` lived in the UK, the HTML source of the 'Country' row would be as follows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Country:</td>
@ -1311,8 +1389,7 @@ the item label property applies to the map value.
@@ -1311,8 +1389,7 @@ the item label property applies to the map value.
This tag renders an HTML `textarea` element. The following HTML shows typical output for it:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<tr>
<td>Notes:</td>
@ -1329,16 +1406,14 @@ This tag renders an HTML `input` tag with the `type` set to `hidden` with the bo
@@ -1329,16 +1406,14 @@ This tag renders an HTML `input` tag with the `type` set to `hidden` with the bo
an unbound hidden value, use the HTML `input` tag with the `type` set to `hidden`.
The following HTML shows typical output for it:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form:hidden path="house"/>
----
If we choose to submit the `house` value as a hidden one, the HTML would be as follows:
@ -1356,8 +1431,8 @@ Assume that we want to display all error messages for the `firstName` and `lastN
@@ -1356,8 +1431,8 @@ Assume that we want to display all error messages for the `firstName` and `lastN
fields once we submit the form. We have a validator for instances of the `User` class
called `UserValidator`, as the following example shows:
@ -1371,11 +1446,25 @@ called `UserValidator`, as the following example shows:
@@ -1371,11 +1446,25 @@ called `UserValidator`, as the following example shows:
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "required", "Field is required.")
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "lastName", "required", "Field is required.")
}
}
----
The `form.jsp` could be as follows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form:form>
<table>
@ -1404,8 +1493,7 @@ The `form.jsp` could be as follows:
@@ -1404,8 +1493,7 @@ The `form.jsp` could be as follows:
If we submit a form with empty values in the `firstName` and `lastName` fields,
the HTML would be as follows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form method="POST">
<table>
@ -1441,8 +1529,7 @@ shows that the `errors` tag also supports some basic wildcarding functionality.
@@ -1441,8 +1529,7 @@ shows that the `errors` tag also supports some basic wildcarding functionality.
The following example displays a list of errors at the top of the page, followed by
field-specific errors next to the fields:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form:form>
<form:errors path="*" cssClass="errorBox"/>
@ -1468,8 +1555,7 @@ field-specific errors next to the fields:
@@ -1468,8 +1555,7 @@ field-specific errors next to the fields:
The HTML would be as follows:
[source,xml,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<form method="POST">
<span name="*.errors" class="errorBox">Field is required.<br/>Field is required.</span>
@ -1534,8 +1619,7 @@ The preceding example performs an HTTP POST, with the "`real`" DELETE method hid
@@ -1534,8 +1619,7 @@ The preceding example performs an HTTP POST, with the "`real`" DELETE method hid
a request parameter. It is picked up by the `HiddenHttpMethodFilter`, which is defined in
web.xml, as the following example shows:
[source,java,indent=0]
[subs="verbatim,quotes"]
[source,xml,indent=0,subs="verbatim,quotes"]
----
<filter>
<filter-name>httpMethodFilter</filter-name>
@ -1550,8 +1634,8 @@ web.xml, as the following example shows:
@@ -1550,8 +1634,8 @@ web.xml, as the following example shows:
The following example shows the corresponding `@Controller` method:
public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
@ -1559,7 +1643,15 @@ The following example shows the corresponding `@Controller` method:
@@ -1559,7 +1643,15 @@ The following example shows the corresponding `@Controller` method:
fun deletePet(@PathVariable ownerId: Int, @PathVariable petId: Int): String {
clinic.deletePet(petId)
return "redirect:/owners/$ownerId"
}
----
[[mvc-view-jsp-formtaglib-html5]]
==== HTML5 Tags
@ -1603,8 +1695,7 @@ To be able to use Tiles, you have to configure it by using files that contain de
@@ -1603,8 +1695,7 @@ To be able to use Tiles, you have to configure it by using files that contain de
https://tiles.apache.org[]). In Spring, this is done by using the `TilesConfigurer`.
The following example `ApplicationContext` configuration shows how to do so:
@ -1630,8 +1721,7 @@ implementations, the `UrlBasedViewResolver` and the `ResourceBundleViewResolver`
@@ -1630,8 +1721,7 @@ implementations, the `UrlBasedViewResolver` and the `ResourceBundleViewResolver`
You can specify locale-specific Tiles definitions by adding an underscore and then
@ -1657,8 +1747,7 @@ them otherwise in the file names for Tiles definitions.
@@ -1657,8 +1747,7 @@ them otherwise in the file names for Tiles definitions.
The `UrlBasedViewResolver` instantiates the given `viewClass` for each view it has to
resolve. The following bean defines a `UrlBasedViewResolver`:
@ -1674,16 +1763,14 @@ view names and view classes that the resolver can use. The following example sho
@@ -1674,16 +1763,14 @@ view names and view classes that the resolver can use. The following example sho
definition for a `ResourceBundleViewResolver` and the corresponding view names and view
@ -1725,8 +1812,7 @@ configuration, scoped beans, and so on. Note that you need to define one Spring
@@ -1725,8 +1812,7 @@ configuration, scoped beans, and so on. Note that you need to define one Spring
for each preparer name (as used in your Tiles definitions). The following example shows
how to define a `SpringBeanPreparerFactory` property on a `TilesConfigurer` bean:
public class SampleContentRssView extends AbstractRssFeedView {
@ -1801,6 +1902,24 @@ Similar requirements apply for implementing `AbstractRssFeedView`, as the follow
@@ -1801,6 +1902,24 @@ Similar requirements apply for implementing `AbstractRssFeedView`, as the follow
A controller can return such a view either from an external view definition
(referencing it by name) or as a `View` instance from the handler method.
@ -1965,24 +2099,38 @@ Configuration is standard for a simple Spring web application: The MVC configura
@@ -1965,24 +2099,38 @@ Configuration is standard for a simple Spring web application: The MVC configura
has to define an `XsltViewResolver` bean and regular MVC annotation configuration.
fun xsltViewResolver() = XsltViewResolver().apply {
setPrefix("/WEB-INF/xsl/")
setSuffix(".xslt")
}
}
----
[[mvc-view-xslt-controllercode]]
@ -1993,8 +2141,8 @@ We also need a Controller that encapsulates our word-generation logic.
@@ -1993,8 +2141,8 @@ We also need a Controller that encapsulates our word-generation logic.
The controller logic is encapsulated in a `@Controller` class, with the