SPR-7912 Add tests for FormattingConversionServiceFactoryBean, update reference docs, and remove mvc:formatters

This commit is contained in:
Rossen Stoyanchev
2011-01-27 11:26:19 +00:00
parent 149348c907
commit abff2b959b
7 changed files with 350 additions and 192 deletions

View File

@@ -1279,7 +1279,7 @@ public void handle(@RequestBody String body, Writer writer) throws IOException {
the <classname>AnnotationMethodHandlerAdapter</classname> is extended
to support the <classname>@RequestBody</classname> and has the
following <interfacename>HttpMessageConverters</interfacename>
registered by default:</para>
registered by default if not using the MVC namespace:</para>
<itemizedlist>
<listitem>
@@ -1301,16 +1301,12 @@ public void handle(@RequestBody String body, Writer writer) throws IOException {
<para><classname>SourceHttpMessageConverter</classname> converts
to/from a javax.xml.transform.Source.</para>
</listitem>
<listitem>
<para><classname>MarshallingHttpMessageConverter</classname>
converts to/from an object using the
<classname>org.springframework.oxm</classname> package.</para>
</listitem>
</itemizedlist>
<para>For more information on these converters, see <link
linkend="rest-message-conversion">Message Converters</link>.</para>
linkend="rest-message-conversion">Message Converters</link>.
Also see <xref linkend="mvc-annotation-driven"/> for information
on the default message converters set up by the MVC namespace.</para>
<para>The <classname>MarshallingHttpMessageConverter</classname>
requires a <interfacename>Marshaller</interfacename> and
@@ -3313,13 +3309,69 @@ public class SimpleController {
</listitem>
<listitem>
<para>
Support for reading and writing XML, if JAXB is present on the classpath.
HttpMessageConverter support for @RequestBody method parameters and @ResponseBody method return values.
</para>
</listitem>
<listitem>
<para>
Support for reading and writing JSON, if Jackson is present on the classpath.
This is the complete list of HttpMessageConverters set up by mvc:annotation-driven:
<itemizedlist>
<listitem>
<para><classname>ByteArrayHttpMessageConverter</classname>
converts byte arrays.</para>
</listitem>
<listitem>
<para><classname>StringHttpMessageConverter</classname> converts
strings.</para>
</listitem>
<listitem>
<para><classname>ResourceHttpMessageConverter</classname> converts
to/from <classname>org.springframework.core.io.Resource</classname>
for all media types.</para>
</listitem>
<listitem>
<para><classname>SourceHttpMessageConverter</classname> converts
to/from a <classname>javax.xml.transform.Source</classname>.</para>
</listitem>
<listitem>
<para><classname>FormHttpMessageConverter</classname> converts
form data to/from a <classname>MultiValueMap&lt;String, String&gt;</classname>.</para>
</listitem>
<listitem>
<para><classname>Jaxb2RootElementHttpMessageConverter</classname>
converts Java objects to/from XML -- added if JAXB2 is present
on the classpath.
</para>
</listitem>
<listitem>
<para><classname>MappingJacksonHttpMessageConverter</classname>
converts to/from JSON -- added if Jackson is present on the classpath.
</para>
</listitem>
<listitem>
<para><classname>AtomFeedHttpMessageConverter</classname>
converts Atom feeds -- added if Rome is present on the classpath.
</para>
</listitem>
<listitem>
<para><classname>RssChannelHttpMessageConverter</classname>
converts RSS feeds -- added if Rome is present on the classpath.
</para>
</listitem>
</itemizedlist>
</para>
<note>
<para>
This list of HttpMessageConverters used can be replaced through
the mvc:message-converters sub-element of mvc:annotation-driven.
</para>
</note>
</listitem>
</orderedlist>
A typical usage is shown below:

View File

@@ -172,17 +172,23 @@
<surname>Gierke</surname>
</author>
<author>
<firstname>Rossen</firstname>
<surname>Stoyanchev</surname>
</author>
</authorgroup>
<copyright>
<year>2004-2010</year>
<year>2004-2011</year>
<holder>Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu,
Rob Harrop, Alef Arendsen, Thomas Risberg, Darren Davison, Dmitriy
Kopylenko, Mark Pollack, Thierry Templier, Erwin Vervaet, Portia Tung,
Ben Hale, Adrian Colyer, John Lewis, Costin Leau, Mark Fisher, Sam
Brannen, Ramnivas Laddad, Arjen Poutsma, Chris Beams, Tareq Abedrabbo,
Andy Clement, Dave Syer, Oliver Gierke</holder>
Andy Clement, Dave Syer, Oliver Gierke, Rossen Stoyanchev</holder>
</copyright>
<legalnotice>

View File

@@ -1350,41 +1350,72 @@ public interface AnnotationFormatterFactory<A extends Annotation> {
<section id="format-FormatterRegistry-SPI">
<title>FormatterRegistry SPI</title>
<para> At runtime, Formatters are registered in a FormatterRegistry. The
FormatterRegistry SPI allows you to configure Formatting rules
centrally, instead of duplicating such configuration across your
Controllers. For example, you might want to enforce that all Date fields
are formatted a certain way, or fields with a specific annotation are
formatted in a certain way. With a shared FormatterRegistry, you define
these rules once and they are applied whenever formatting is needed. </para>
<para> The FormatterRegistry is an SPI for registering formatters and
converters. <classname>FormattingConversionService</classname> is
an implementation of FormatterRegistry suitable for most environments.
This implementation may be configured programatically or declaratively
as a Spring bean using
<classname>FormattingConversionServiceFactoryBean</classname>.
Because this implemementation also implements
<classname>ConversionService</classname>, it can be directly
configured for use with Spring's DataBinder and the Spring Expression
Language (SpEL).
</para>
<para> Review the FormatterRegistry SPI below: </para>
<programlisting language="java"><![CDATA[package org.springframework.format;
public interface FormatterRegistry {
public interface FormatterRegistry extends ConverterRegistry {
void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser);
void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter);
void addFormatterForFieldType(Formatter<?> formatter);
void addFormatterForAnnotation(AnnotationFormatterFactory<?, ?> factory);
}]]></programlisting>
<para> As shown above, Formatters can be registered by fieldType or
annotation. <classname>FormattingConversionService</classname> is the
implementation of <classname>FormatterRegistry</classname> suitable for
most environments. This implementation may be configured
programatically, or declaratively as a Spring bean using
<classname>FormattingConversionServiceFactoryBean</classname>. Because
this implemementation also implements
<classname>ConversionService</classname>, it can be directly configured
for use with Spring's DataBinder and the Spring Expression Language
(SpEL). </para>
annotation.
</para>
<para> The FormatterRegistry SPI allows you to configure Formatting rules
centrally, instead of duplicating such configuration across your
Controllers. For example, you might want to enforce that all Date fields
are formatted a certain way, or fields with a specific annotation are
formatted in a certain way. With a shared FormatterRegistry, you define
these rules once and they are applied whenever formatting is needed.
</para>
</section>
<section id="format-configuring-FormatterRegistry">
<section id="format-FormatterRegistrar-SPI">
<title>FormatterRegistrar SPI</title>
<para> The FormatterRegistrar is an SPI for registering formatters and
converters through the FormatterRegistry:
</para>
<programlisting language="java"><![CDATA[package org.springframework.format;
public interface FormatterRegistrar {
void registerFormatters(FormatterRegistry registry);
}]]></programlisting>
<para> A FormatterRegistrar is useful when registering multiple related
converters and formatters for a given formatting category, such as Date
formatting. It can also be useful where declarative registration is
insufficient. For example when a formatter needs to be indexed under a
specific field type different from its own &lt;T&gt; or when registering
a Printer/Parser pair. The next section provides more information on
converter and formatter registration.
</para>
</section>
<section id="format-configuring-FormattingConverionService">
<title>Configuring Formatting in Spring MVC</title>
<para> In a Spring MVC application, you may configure a custom
@@ -1419,7 +1450,9 @@ public interface FormatterRegistry {
classpath. </para>
<para> To inject a ConversionService instance with custom formatters and
converters registered, set the conversion-service attribute: </para>
converters registered, set the conversion-service attribute and then
specify custom converters, formatters, or FormatterRegistrars as properties
of the FormattingConversionServiceFactoryBean: </para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
@@ -1433,15 +1466,35 @@ public interface FormatterRegistry {
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean"/>
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>
]]></programlisting>
<para> A custom ConversionService instance is often constructed by a
FactoryBean that internally registers custom Formatters and Converters
programatically before the ConversionService is returned. See
FormattingConversionServiceFactoryBean for an example. </para>
<note>
<para> See <xref linkend="format-FormatterRegistrar-SPI"/> and
the <classname>FormattingConversionServiceFactoryBean</classname>
for more information on when to use FormatterRegistrars.
</para>
</note>
</section>
</section>