Refactor Spring MVC related conversion/validation docs

Conversion and validation documentation related to Spring MVC is now
consolidated in the Spring MVC chapter with references to and from
the Validation and Data Binding chapter.

Examples have been updated to include MVC Java config as well.
This commit is contained in:
Rossen Stoyanchev
2015-07-07 12:21:41 -04:00
parent 7cac5d60a1
commit 726a47dd81
2 changed files with 149 additions and 235 deletions

View File

@@ -957,7 +957,7 @@ either of the Converter, ConverterFactory, or GenericConverter interfaces.
----
It is also common to use a ConversionService within a Spring MVC application. See
<<format-configuring-formatting-mvc>> for details on use with `<mvc:annotation-driven/>`.
<<mvc-config-conversion>> in the Spring MVC chapter.
In certain situations you may wish to apply formatting during conversion. See
<<format-FormatterRegistry-SPI>> for details on using
@@ -1308,85 +1308,8 @@ converter and formatter registration.
[[format-configuring-formatting-mvc]]
=== Configuring Formatting in Spring MVC
In a Spring MVC application, you may configure a custom ConversionService instance
explicitly as an attribute of the `annotation-driven` element of the MVC namespace. This
ConversionService will then be used anytime a type conversion is required during
Controller model binding. If not configured explicitly, Spring MVC will automatically
register default formatters and converters for common types such as numbers and dates.
To rely on default formatting rules, no custom configuration is required in your Spring
MVC config XML:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
</beans>
----
With this one-line of configuration, default formatters for Numbers and Date types will
be installed, including support for the @NumberFormat and @DateTimeFormat annotations.
Full support for the Joda Time formatting library is also installed if Joda Time is
present on the classpath.
To inject a ConversionService instance with custom formatters and converters registered,
set the conversion-service attribute and then specify custom converters, formatters, or
FormatterRegistrars as properties of the FormattingConversionServiceFactoryBean:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="org.example.MyConverter"/>
</set>
</property>
<property name="formatters">
<set>
<bean class="org.example.MyFormatter"/>
<bean class="org.example.MyAnnotationFormatterFactory"/>
</set>
</property>
<property name="formatterRegistrars">
<set>
<bean class="org.example.MyFormatterRegistrar"/>
</set>
</property>
</bean>
</beans>
----
[NOTE]
====
See <<format-FormatterRegistrar-SPI>> and the `FormattingConversionServiceFactoryBean`
for more information on when to use FormatterRegistrars.
====
See <<mvc-config-conversion>> in the Spring MVC chapter.
@@ -1479,7 +1402,7 @@ If you are using Spring MVC remember to explicitly configure the conversion serv
is used. For Java based `@Configuration` this means extending the
`WebMvcConfigurationSupport` class and overriding the `mvcConversionService()` method.
For XML you should use the `'conversion-service'` attribute of the
`mvc:annotation-driven` element. See <<format-configuring-formatting-mvc>> for details.
`mvc:annotation-driven` element. See <<mvc-config-conversion>> for details.
@@ -1707,131 +1630,6 @@ locally on a DataBinder instance. See <<validation-mvc-configuring>>.
[[validation-mvc]]
=== Spring MVC 3 Validation
Beginning with Spring 3, Spring MVC has the ability to automatically validate
`@Controller` inputs. In previous versions it was up to the developer to manually invoke
validation logic.
[[validation-mvc-triggering]]
==== Triggering @Controller Input Validation
To trigger validation of a `@Controller` input, simply annotate the input argument as
++@Valid++:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Controller
public class MyController {
@RequestMapping(path="/foo", method=RequestMethod.POST)
public void processFoo(**@Valid** Foo foo) { /* ... */ }
----
Spring MVC will validate a @Valid object after binding so-long as an appropriate
Validator has been configured.
[NOTE]
====
The @Valid annotation is part of the standard JSR-303 Bean Validation API, and is not a
Spring-specific construct.
====
[[validation-mvc-configuring]]
==== Configuring a Validator for use by Spring MVC
The `Validator` instance invoked when a `@Valid` method argument is encountered may be
configured in two ways. First, you may call `binder.setValidator(Validator)` within a
++@Controller++'s `@InitBinder` callback. This allows you to configure a `Validator`
instance per `@Controller` class:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Controller
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new FooValidator());
}
@RequestMapping(path="/foo", method=RequestMethod.POST)
public void processFoo(@Valid Foo foo) { ... }
}
----
Second, you may call `setValidator(Validator)` on the global `WebBindingInitializer`. This
allows you to configure a `Validator` instance across all `@Controller` classes. This can be
achieved easily by using the Spring MVC namespace:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven validator="globalValidator"/>
</beans>
----
To combine a global and a local validator, configure the global validator as shown above
and then add a local validator:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Controller
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new FooValidator());
}
}
----
[[validation-mvc-jsr303]]
==== Configuring a JSR-303/JSR-349 Validator for use by Spring MVC
With Bean Validation, a single `javax.validation.Validator` instance typically validates
__all__ model objects that declare validation constraints. To configure such a JSR-303
backed Validator with Spring MVC, simply add a Bean Validation provider, such as
Hibernate Validator, to your classpath. Spring MVC will detect it and automatically
enable Bean Validation support across all Controllers.
The Spring MVC configuration required to enable Bean Validation support is shown below:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- JSR-303/JSR-349 support will be detected on classpath and enabled automatically -->
<mvc:annotation-driven/>
</beans>
----
With this minimal configuration, anytime a `@Valid` `@Controller` input is encountered, it
will be validated by the Bean Validation provider. That provider, in turn, will enforce
any constraints declared against the input. Any ++ConstraintViolation++s will automatically
be exposed as errors in the `BindingResult` renderable by standard Spring MVC form tags.
See <<mvc-config-validation>> in the Spring MVC chapter.

View File

@@ -4567,10 +4567,34 @@ the classpath.
=== Customizing the Provided Configuration
To customize the default configuration in Java you simply implement the
`WebMvcConfigurer` interface or more likely extend the class `WebMvcConfigurerAdapter`
and override the methods you need. Below is an example of some of the available methods
to override. See
{javadoc-baseurl}/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.html[`WebMvcConfigurer`]
for a list of all methods and the javadocs for further details:
and override the methods you need:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
// Override configuration methods...
}
----
To customize the default configuration of `<mvc:annotation-driven />` check what
attributes and sub-elements it supports. You can view the
http://schema.spring.io/mvc/spring-mvc.xsd[Spring MVC XML schema] or use the code
completion feature of your IDE to discover what attributes and sub-elements are
available.
[[mvc-config-conversion]]
=== Conversion and Formatting
By default formatters for Numbers and Date types are installed, including support for the @NumberFormat
and @DateTimeFormat annotations. Full support for the Joda Time formatting library is also installed
if Joda Time is present on the classpath. To register custom formatters and converters override
the `addFormatters` method:
[source,java,indent=0]
[subs="verbatim,quotes"]
@@ -4580,44 +4604,136 @@ for a list of all methods and the javadocs for further details:
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
protected void addFormatters(FormatterRegistry registry) {
public void addFormatters(FormatterRegistry registry) {
// Add formatters and/or converters
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// Configure the list of HttpMessageConverters to use
}
}
----
To customize the default configuration of `<mvc:annotation-driven />` check what
attributes and sub-elements it supports. You can view the
http://schema.spring.io/mvc/spring-mvc.xsd[Spring MVC XML schema] or use the code
completion feature of your IDE to discover what attributes and sub-elements are
available. The sample below shows a subset of what is available:
In the MVC namespace the same defaults apply when `<mvc:annotation-driven>` is added.
To register custom formatters and converters simply supply a `ConversionService`:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters>
<bean class="org.example.MyHttpMessageConverter"/>
<bean class="org.example.MyOtherHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<list>
<bean class="org.example.MyFormatter"/>
<bean class="org.example.MyOtherFormatter"/>
</list>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="org.example.MyConverter"/>
</set>
</property>
<property name="formatters">
<set>
<bean class="org.example.MyFormatter"/>
<bean class="org.example.MyAnnotationFormatterFactory"/>
</set>
</property>
<property name="formatterRegistrars">
<set>
<bean class="org.example.MyFormatterRegistrar"/>
</set>
</property>
</bean>
</beans>
----
[NOTE]
====
See <<format-FormatterRegistrar-SPI>> and the `FormattingConversionServiceFactoryBean`
for more information on when to use FormatterRegistrars.
====
[[mvc-config-validation]]
=== Validation
Spring provides a <<validator,Validator interface>> that can be used for validation in all layers
of an application. In Spring MVC you can configure it for use as a global `Validator` instance, to be used
whenever an `@Valid` or `@Validated` controller method argument is encountered, and/or as a local
`Validator` within a controller through an `@InitBinder` method. Global and local validator
instances can be combined to provide composite validation.
Spring also <<validation-beanvalidation-overview,supports JSR-303/JSR-349>> Bean Validation
via `LocalValidatorFactoryBean` which adapts the Spring `org.springframework.validation.Validator`
interface to the Bean Validation `javax.validation.Validator` contract. This class can be
plugged into Spring MVC as a global validator as described next.
By default use of `@EnableWebMvc` or `<mvc:annotation-driven>` automatically registers Bean
Validation support in Spring MVC through the `LocalValidatorFactoryBean` when a Bean Validation
provider is such as Hibernate Validator is detected on the classpath.
Alternatively you can configure your own global `Validator` instance:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public Validator getValidator(); {
// return "global" validator
}
}
----
and in XML:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven validator="globalValidator"/>
</beans>
----
To combine global with local validation, simply add one or more local validator(s):
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Controller
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new FooValidator());
}
}
----
With this minimal configuration anytime an `@Valid` or `@Validated` method argument is encountered, it
will be validated by the configured validators. Any validation violations will automatically
be exposed as errors in the `BindingResult` accessible as a method argument and also renderable
in Spring MVC HTML views.
[[mvc-config-interceptors]]