提交 2aac0aac 编写于 作者: K Keith Donald

polish

上级 a8058193
......@@ -912,23 +912,23 @@ public class MyService {
<section id="ui.format">
<title>Spring 3 Field Formatting</title>
<para>
<link linkend="core.convert"><filename>core.convert</filename></link> is a simple, general-purpose type conversion system.
It provides a strongly-typed Converter SPI for implementing <emphasis>one-way</emphasis> conversion logic from one type to another and is not limited to just converting Strings.
<link linkend="core.convert"><filename>core.convert</filename></link> 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 <classname>Short</classname> to a <classname>Long</classname> to complete an <function>expression.setValue(Object bean, Object value)</function> attempt, the core.convert system performs the coercion.
</para>
<para>
Now consider the type conversion requirements of a typical client environment such as a web or desktop application.
In such environments, you typically convert <emphasis>from String</emphasis> to support the client postback process, as well as back <emphasis>to String</emphasis> to support the rendering process.
The more general <emphasis>core.convert</emphasis> Converter SPI does not address this specific common scenario directly.
To directly address this, Spring 3 introduces a conveient <emphasis>format</emphasis> SPI that provides a simple and robust alternative to PropertyEditors in a client environment.
In such environments, you typically convert <emphasis>from String</emphasis> to support the client postback process, as well as back <emphasis>to String</emphasis> to support the view rendering process.
The more general <emphasis>core.convert</emphasis> Converter SPI does not address this scenario directly.
To directly address this, Spring 3 introduces a conveient <emphasis>format</emphasis> SPI that provides a simple and robust alternative to PropertyEditors for client environments.
</para>
<para>
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.
</para>
<section id="ui-format-Formatter-SPI">
<section id="format-Formatter-SPI">
<title>Formatter SPI</title>
<para>
The <literal>org.springframework.format</literal> SPI to implement field formatting logic is simple and strongly typed:
......@@ -951,7 +951,7 @@ public interface Formatter<T> extends Printer<T>, Parser<T> {
</programlisting>
<para>
To create your own Formatter, simply implement the Formatter interface above.
Parameterize T to be the type of object you are formatting, for example, <classname>java.lang.BigDecimal</classname>.
Parameterize T to be the type of object you are formatting, for example, <classname>java.util.Date</classname>.
Implement the <methodname>print</methodname> operation to print an instance of T for display in the client locale.
Implement the <methodname>parse</methodname> 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<T> extends Printer<T>, Parser<T> {
<para>
Several Formatter implementations are provided in <filename>format</filename>subpackages as a convenience.
The <filename>datetime</filename> package provides a DateFormatter to format java.util.Date objects with a java.text.DateFormat.
The <filename>number</filename> package provides a DecimalFormatter, IntegerFormatter, CurrencyFormatter, and PercentFormatter to format java.lang.Number objects using a java.text.NumberFormat.
The <filename>number</filename> package provides a NumberFormatter, CurrencyFormatter, and PercentFormatter to format java.lang.Number objects using a java.text.NumberFormat.
The <filename>datetime.joda</filename> package provides comprehensive datetime formatting support based on the <ulink url="http://joda-time.sourceforge.net">Joda Time library</ulink>.
</para>
<para>
......@@ -1002,13 +1002,13 @@ public final class DateFormatter implements Formatter<Date> {
The Spring team welcomes community-driven Formatter contributions; see <ulink url="http://jira.springframework.org">http://jira.springframework.org</ulink> to contribute.
</para>
</section>
<section id="ui-format-CustomFormatAnnotations">
<section id="format-CustomFormatAnnotations">
<title>Custom Format Annotations</title>
<para>
Field formatting can be triggered by annotating model properties.
To bind a custom annotation to a Formatter instance, implement AnnotationFormatterFactory:
</para>
<programlisting language="java"><![CDATA[
<programlisting language="java"><![CDATA[
package org.springframework.format;
public interface AnnotationFormatterFactory<A extends Annotation> {
......@@ -1019,45 +1019,91 @@ public interface AnnotationFormatterFactory<A extends Annotation> {
Parser<?> getParser(A annotation, Class<?> fieldType);
}]]></programlisting>
<para>
Parameterize A to be the field annotationType you wish to associate formatting logic with, for example <code>org.springframework.format.annotation.DateTimeFormat</code>.
Implement the <methodname>getFieldTypes</methodname> operation return the types of fields the annotation may be used on.
Implement the <methodname>getPrinter</methodname> operation to return the Printer to print the value of an annotated field.
Implement the <methodname>getParser</methodname> operation to return the Parser to parse the value of an annotated field.
Take care to ensure your AnnotationFormatterFactory implementation is thread-safe.
</para>
<para>
The example implementation below binds a @DecimalFormat instance to a Formatter instance.
This particular annotation allows the NumberFormat pattern to be configured.
</para>
<programlisting language="java"><![CDATA[
public class DecimalAnnotationFormatterFactory implements AnnotationFormatterFactory<DecimalFormat, Number> {
Formatter<Number> getFormatter(DecimalFormat annotation) {
DecimalFormatter formatter = DecimalFormatter();
formatter.setPattern(annotation.value());
return formatter;
}
}]]></programlisting>
<para>
Then, to trigger formatting, simply annotate a property with @DecimalFormat in your model:
</para>
<programlisting language="java"><![CDATA[
}]]>
</programlisting>
<para>
Parameterize A to be the field annotationType you wish to associate formatting logic with, for example <code>org.springframework.format.annotation.DateTimeFormat</code>.
Implement the <methodname>getFieldTypes</methodname> operation return the types of fields the annotation may be used on.
Implement the <methodname>getPrinter</methodname> operation to return the Printer to print the value of an annotated field.
Implement the <methodname>getParser</methodname> operation to return the Parser to parse the value of an annotated field.
Take care to ensure your AnnotationFormatterFactory implementation is thread-safe.
</para>
<para>
The example implementation below binds a @NumberFormat instance to a Formatter instance.
This particular annotation allows the NumberFormat style or pattern to be specified:
</para>
<programlisting language="java"><![CDATA[
public final class NumberFormatAnnotationFormatterFactory implements AnnotationFormatterFactory<NumberFormat> {
public Set<Class<?>> getFieldTypes() {
Set<Class<?>> fieldTypes = new HashSet<Class<?>>(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<Number> getPrinter(NumberFormat annotation, Class<?> fieldType) {
return configureFormatterFrom(annotation, fieldType);
}
public Parser<Number> getParser(NumberFormat annotation, Class<?> fieldType) {
return configureFormatterFrom(annotation, fieldType);
}
private Formatter<Number> 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();
}
}
}
}]]>
</programlisting>
<para>
Then, to trigger formatting, simply annotate a property with @NumberFormat in your model:
</para>
<programlisting language="java"><![CDATA[
public class MyModel {
@DecimalFormat("#,###")
@NumberFormat(style=Style.CURRENCY)
private BigDecimal decimal;
}]]></programlisting>
</section>
}]]>
</programlisting>
<para>
A format annotation API exists in the <filename>org.springframework.format.annotation</filename> 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.
</para>
<para>
The example below shows use of the DateTimeFormat annotation to format a java.util.Date as a ISO Date (yyyy-MM-dd):
</para>
<programlisting language="java"><![CDATA[
public class MyModel {
@DateTimeFormat(iso=ISO.DATE)
private Date date;
}]]>
</programlisting>
</section>
<section id="ui-format-FormatterRegistry-SPI">
<section id="format-FormatterRegistry-SPI">
<title>FormatterRegistry SPI</title>
<para>
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.
</para>
......@@ -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);
}]]></programlisting>
<para>
As shown above, Formatters may be registered by field type or annotation.
<classname>GenericFormatterRegistry</classname> 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.
<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 with <classname>FormattingConversionServiceFactoryBean</classname>.
Because it also implements <classname>ConversionService</classname>, it can be configured for use with Spring's DataBinder as well as SpEL.
</para>
</section>
<section id="ui-format-configuring-FormatterRegistry">
<title>Configuring a FormatterRegistry</title>
<section id="format-configuring-FormatterRegistry">
<title>Configuring Formatting in Spring MVC</title>
<para>
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 <literal>annotation-driven</literal> 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.
</para>
<note>
<para>
If no FormatterRegistry is configured, the original PropertyEditor-based system is used.
</para>
</note>
<para>
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:
</para>
<programlisting language="xml"><![CDATA[
<!-- Invokes Spring MVC @Controller methods -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<!-- Configures Spring MVC DataBinder instances -->
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="formatterRegistry">
<bean class="org.springframework.format.support.GenericFormatterRegistry">
<property name="formatters">
<list>
<!-- Register Formatter beans here -->
</list>
</property>
<property name="annotationFormatterFactories">
<list>
<!-- Register any AnnotationFormatterFactory beans here -->
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>]]>
<?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-3.0.xsd">
<mvc:annotation-driven/>
</beans>
]]>
</programlisting>
<para>
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.
</para>
<para>
To inject a ConversionService instance with custom formatters/converters registered, set the conversion-service attribute:
</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"
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-3.0.xsd">
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
</beans>
]]>
</programlisting>
<para>
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.
</para>
</section>
</section>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册