From 2aac0aace4b175b86592adc0b3d3fb610f8cff3e Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 11 Nov 2009 20:44:32 +0000 Subject: [PATCH] polish --- spring-framework-reference/src/validation.xml | 224 +++++++++++------- 1 file changed, 139 insertions(+), 85 deletions(-) diff --git a/spring-framework-reference/src/validation.xml b/spring-framework-reference/src/validation.xml index b56226a48a..2df540a1fd 100644 --- a/spring-framework-reference/src/validation.xml +++ b/spring-framework-reference/src/validation.xml @@ -912,23 +912,23 @@ public class MyService {
Spring 3 Field Formatting - core.convert is a simple, general-purpose type conversion system. - It provides a strongly-typed Converter SPI for implementing one-way conversion logic from one type to another and is not limited to just converting Strings. + core.convert is a general-purpose type conversion system. + It provides a strongly-typed Converter SPI for implementing conversion logic from one type to another and is not limited to just converting Strings. As discussed in the previous section, a Spring Container can be configured to use this system to bind bean property values. - In addition, both the Spring Expression Language (SpEL) and DataBinder can use this system to coerce values. + In addition, both the Spring Expression Language (SpEL) and DataBinder can use this system to bind values. For example, when SpEL needs to coerce a Short to a Long to complete an expression.setValue(Object bean, Object value) attempt, the core.convert system performs the coercion. Now consider the type conversion requirements of a typical client environment such as a web or desktop application. - In such environments, you typically convert from String to support the client postback process, as well as back to String to support the rendering process. - The more general core.convert Converter SPI does not address this specific common scenario directly. - To directly address this, Spring 3 introduces a conveient format SPI that provides a simple and robust alternative to PropertyEditors in a client environment. + In such environments, you typically convert from String to support the client postback process, as well as back to String to support the view rendering process. + The more general core.convert Converter SPI does not address this scenario directly. + To directly address this, Spring 3 introduces a conveient format SPI that provides a simple and robust alternative to PropertyEditors for client environments. In general, use the Converter SPI when you need to implement general-purpose type conversion logic. - Use Formatters when you're working in a client environment, such as an HTML form of a web application and need to apply String parsing, printing, and localization logic to form field values. + Use Formatters when you're working in a client environment, such as a web application, and need to apply String parsing, printing, and localization logic to form field values. -
+
Formatter SPI The org.springframework.format SPI to implement field formatting logic is simple and strongly typed: @@ -951,7 +951,7 @@ public interface Formatter extends Printer, Parser { To create your own Formatter, simply implement the Formatter interface above. - Parameterize T to be the type of object you are formatting, for example, java.lang.BigDecimal. + Parameterize T to be the type of object you are formatting, for example, java.util.Date. Implement the print operation to print an instance of T for display in the client locale. Implement the parse operation to parse an instance of T from the formatted representation returned from the client locale. Your Formatter should throw a ParseException or IllegalArgumentException if a parse attempt fails. @@ -960,7 +960,7 @@ public interface Formatter extends Printer, Parser { Several Formatter implementations are provided in formatsubpackages as a convenience. The datetime package provides a DateFormatter to format java.util.Date objects with a java.text.DateFormat. - The number package provides a DecimalFormatter, IntegerFormatter, CurrencyFormatter, and PercentFormatter to format java.lang.Number objects using a java.text.NumberFormat. + The number package provides a NumberFormatter, CurrencyFormatter, and PercentFormatter to format java.lang.Number objects using a java.text.NumberFormat. The datetime.joda package provides comprehensive datetime formatting support based on the Joda Time library. @@ -1002,13 +1002,13 @@ public final class DateFormatter implements Formatter { The Spring team welcomes community-driven Formatter contributions; see http://jira.springframework.org to contribute.
-
+
Custom Format Annotations Field formatting can be triggered by annotating model properties. To bind a custom annotation to a Formatter instance, implement AnnotationFormatterFactory: - { @@ -1019,45 +1019,91 @@ public interface AnnotationFormatterFactory { Parser getParser(A annotation, Class fieldType); -}]]> - - Parameterize A to be the field annotationType you wish to associate formatting logic with, for example org.springframework.format.annotation.DateTimeFormat. - Implement the getFieldTypes operation return the types of fields the annotation may be used on. - Implement the getPrinter operation to return the Printer to print the value of an annotated field. - Implement the getParser operation to return the Parser to parse the value of an annotated field. - Take care to ensure your AnnotationFormatterFactory implementation is thread-safe. - - - The example implementation below binds a @DecimalFormat instance to a Formatter instance. - This particular annotation allows the NumberFormat pattern to be configured. - - { - - Formatter getFormatter(DecimalFormat annotation) { - DecimalFormatter formatter = DecimalFormatter(); - formatter.setPattern(annotation.value()); - return formatter; - } -}]]> - - Then, to trigger formatting, simply annotate a property with @DecimalFormat in your model: - - + + + Parameterize A to be the field annotationType you wish to associate formatting logic with, for example org.springframework.format.annotation.DateTimeFormat. + Implement the getFieldTypes operation return the types of fields the annotation may be used on. + Implement the getPrinter operation to return the Printer to print the value of an annotated field. + Implement the getParser operation to return the Parser to parse the value of an annotated field. + Take care to ensure your AnnotationFormatterFactory implementation is thread-safe. + + + The example implementation below binds a @NumberFormat instance to a Formatter instance. + This particular annotation allows the NumberFormat style or pattern to be specified: + + { + + public Set> getFieldTypes() { + Set> fieldTypes = new HashSet>(7); + fieldTypes.add(Short.class); + fieldTypes.add(Integer.class); + fieldTypes.add(Long.class); + fieldTypes.add(Float.class); + fieldTypes.add(Double.class); + fieldTypes.add(BigDecimal.class); + fieldTypes.add(BigInteger.class); + return fieldTypes; + } + + public Printer getPrinter(NumberFormat annotation, Class fieldType) { + return configureFormatterFrom(annotation, fieldType); + } + + public Parser getParser(NumberFormat annotation, Class fieldType) { + return configureFormatterFrom(annotation, fieldType); + } + + private Formatter configureFormatterFrom(NumberFormat annotation, Class fieldType) { + if (!annotation.pattern().isEmpty()) { + return new NumberFormatter(annotation.pattern()); + } else { + Style style = annotation.style(); + if (style == Style.PERCENT) { + return new PercentFormatter(); + } else if (style == Style.CURRENCY) { + return new CurrencyFormatter(); + } else { + return new NumberFormatter(); + } + } + } +}]]> + + + Then, to trigger formatting, simply annotate a property with @NumberFormat in your model: + + -
+}]]> + + + A format annotation API exists in the org.springframework.format.annotation package. + Use the NumberFormat annotation to apply formatting to java.lang.Number fields. + Use the DateTimeFormat annotation to apply formatting to java.util.Date, java.util.Calendar, java.util.Long, or Joda Time fields. + + + The example below shows use of the DateTimeFormat annotation to format a java.util.Date as a ISO Date (yyyy-MM-dd): + + +
-
+
FormatterRegistry SPI - Formatters can be registered in a FormatterRegistry. - A DataBinder uses this registry to resolve the Formatter to use for a specific field. - This allows you to configure default Formatting rules centrally, rather than duplicating such configuration across your UI Controllers. + When installed, Formatters are registered in a FormatterRegistry. + A FormatterRegistry 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. @@ -1069,60 +1115,68 @@ package org.springframework.format; public interface FormatterRegistry { - void add(Formatter formatter); + void addFormatterForFieldType(Class fieldType, Printer printer, Parser parser); + + void addFormatterForFieldType(Class fieldType, Formatter formatter); - void add(AnnotationFormatterFactory factory); + void addFormatterForAnnotation(AnnotationFormatterFactory factory); }]]> - As shown above, Formatters may be registered by field type or annotation. - GenericFormatterRegistry is the implementation suitable for use in most UI binding environments. - This implementation may be configured programatically or declaratively as a Spring bean. + As shown above, Formatters can be registered by fieldType or annotation. + FormattingConversionService is the implementation of FormatterRegistry suitable for most environments. + This implementation may be configured programatically or declaratively as a Spring bean with FormattingConversionServiceFactoryBean. + Because it also implements ConversionService, it can be configured for use with Spring's DataBinder as well as SpEL.
-
- Configuring a FormatterRegistry +
+ Configuring Formatting in Spring MVC - A FormatterRegistry is designed to be instantiated at application startup, then shared between multiple threads. - In a Spring MVC application, you configure a FormatterRegistry as a property of the WebBindingInitializer. - The FormatterRegistry will then be configured whenever a DataBinder is created by Spring MVC to bind and render model properties. + In a Spring MVC application, you can configure a ConversionService instance explicity as an attribute of the annotation-driven element of the MVC namespace. + This ConversionService will then be used any time type conversion is needed during Controller model binding. + If not configured explicitly, Spring MVC will configure a FormattingConversionService instance that registers default formatters for number and date types. - - - If no FormatterRegistry is configured, the original PropertyEditor-based system is used. - - - To register a FormatterRegistry with Spring MVC, simply configure it as a property of a custom WebBindingInitializer injected into the - Spring MVC AnnotationMethodHandlerAdapter: + To rely on default formatting rules, no explicit configuration is required in your Spring MVC config XML: - - - - - - - - - - - - - - - - - - - - -]]> + + + + + + +]]> + + + With this one-line of configuation, default formatters for Numbers and Date types will be installed, including support for the @NumberFormat and @DateTimeFormat annotations. + This also includes full support for the Joda Time formatting library if Joda Time is present on the classpath. + + + To inject a ConversionService instance with custom formatters/converters registered, set the conversion-service attribute: + + + + + + + + + +]]> - When using the @Formatted annotation, no explicit Formatter or AnnotationFormatterFactory registration is required. - See the JavaDocs for GenericFormatterRegistry for more configuration options. + A custom ConversionService instance is often constructed by a FactoryBean, which internally registers custom Formatters and Converters programatically before the ConversionService is returned. + See FormatingConversionServiceFactoryBean for an example.
-- GitLab