Update ref doc references to Number/Currency/PercentStyleFormatter

Issue: SPR-17022
This commit is contained in:
Juergen Hoeller
2018-07-18 14:43:23 +02:00
parent 19e944bd4f
commit 1e9b2b1c07

View File

@@ -1,4 +1,3 @@
[[validation]]
= Validation, Data Binding, and Type Conversion
@@ -172,6 +171,7 @@ methods it offers can be found in the javadocs.
[[validation-conversion]]
== Resolving codes to error messages
We've talked about databinding and validation. Outputting messages corresponding to
validation errors is the last thing we need to discuss. In the example we've shown
above, we rejected the `name` and the `age` field. If we're going to output the error
@@ -228,6 +228,7 @@ perform actions on that bean, like setting and retrieving properties.
[[beans-beans-conventions]]
=== Setting and getting basic and nested properties
Setting and getting properties is done using the `setPropertyValue(s)` and
`getPropertyValue(s)` methods that both come with a couple of overloaded variants.
They're all described in more detail in the javadocs Spring comes with. What's important
@@ -701,6 +702,7 @@ registration code to be encapsulated in a class and then shared amongst as many
[[core-convert]]
== Spring Type Conversion
Spring 3 introduces a `core.convert` package that provides a general type conversion
system. The system defines an SPI to implement type conversion logic, as well as an API
to execute type conversions at runtime. Within a Spring container, this system can be
@@ -712,6 +714,7 @@ application where type conversion is needed.
[[core-convert-Converter-API]]
=== Converter SPI
The SPI to implement type conversion logic is simple and strongly typed:
[source,java,indent=0]
@@ -722,7 +725,6 @@ The SPI to implement type conversion logic is simple and strongly typed:
public interface Converter<S, T> {
T convert(S source);
}
----
@@ -751,7 +753,6 @@ Consider `StringToInteger` as an example for a typical `Converter` implementatio
public Integer convert(String source) {
return Integer.valueOf(source);
}
}
----
@@ -759,6 +760,7 @@ Consider `StringToInteger` as an example for a typical `Converter` implementatio
[[core-convert-ConverterFactory-SPI]]
=== ConverterFactory
When you need to centralize the conversion logic for an entire class hierarchy, for
example, when converting from String to java.lang.Enum objects, implement
`ConverterFactory`:
@@ -771,7 +773,6 @@ example, when converting from String to java.lang.Enum objects, implement
public interface ConverterFactory<S, R> {
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
----
@@ -811,6 +812,7 @@ Consider the `StringToEnum` ConverterFactory as an example:
[[core-convert-GenericConverter-SPI]]
=== GenericConverter
When you require a sophisticated Converter implementation, consider the GenericConverter
interface. With a more flexible but less strongly typed signature, a GenericConverter
supports converting between multiple source and target types. In addition, a
@@ -828,7 +830,6 @@ by a field annotation, or generic information declared on a field signature.
public Set<ConvertiblePair> getConvertibleTypes();
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
----
@@ -853,6 +854,7 @@ Favor Converter or ConverterFactory for basic type conversion needs.
[[core-convert-ConditionalGenericConverter-SPI]]
==== ConditionalGenericConverter
Sometimes you only want a `Converter` to execute if a specific condition holds true. For
example, you might only want to execute a `Converter` if a specific annotation is present
on the target field. Or you might only want to execute a `Converter` if a specific method,
@@ -866,12 +868,9 @@ such as a `static valueOf` method, is defined on the target class.
public interface ConditionalConverter {
boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}
public interface ConditionalGenericConverter
extends GenericConverter, ConditionalConverter {
public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter {
}
----
@@ -885,6 +884,7 @@ might only match if the target entity type declares a static finder method e.g.
[[core-convert-ConversionService-API]]
=== ConversionService API
The ConversionService defines a unified API for executing type conversion logic at
runtime. Converters are often executed behind this facade interface:
@@ -919,6 +919,7 @@ creating common ConversionService configurations.
[[core-convert-Spring-config]]
=== Configuring a ConversionService
A ConversionService is a stateless object designed to be instantiated at application
startup, then shared between multiple threads. In a Spring application, you typically
configure a ConversionService instance per Spring container (or ApplicationContext).
@@ -971,6 +972,7 @@ In certain situations you may wish to apply formatting during conversion. See
[[core-convert-programmatic-usage]]
=== Using a ConversionService programmatically
To work with a ConversionService instance programmatically, simply inject a reference to
it like you would for any other bean:
@@ -1024,6 +1026,7 @@ no need to create a specific converter to convert from a `Collection` of `S` to
[[format]]
== Spring Field Formatting
As discussed in the previous section, <<core-convert, `core.convert`>> is a
general-purpose type conversion system. It provides a unified ConversionService API as
well as a strongly-typed Converter SPI for implementing conversion logic from one type
@@ -1051,6 +1054,7 @@ ConversionService provides a unified type conversion API for both SPIs.
[[format-Formatter-SPI]]
=== Formatter SPI
The Formatter SPI to implement field formatting logic is simple and strongly typed:
[source,java,indent=0]
@@ -1068,6 +1072,7 @@ Where Formatter extends from the Printer and Parser building-block interfaces:
[subs="verbatim,quotes"]
----
public interface Printer<T> {
String print(T fieldValue, Locale locale);
}
----
@@ -1078,6 +1083,7 @@ Where Formatter extends from the Printer and Parser building-block interfaces:
import java.text.ParseException;
public interface Parser<T> {
T parse(String clientValue, Locale locale) throws ParseException;
}
----
@@ -1091,8 +1097,8 @@ should throw a ParseException or IllegalArgumentException if a parse attempt fai
care to ensure your Formatter implementation is thread-safe.
Several Formatter implementations are provided in `format` subpackages as a convenience.
The `number` package provides a `NumberFormatter`, `CurrencyFormatter`, and
`PercentFormatter` to format `java.lang.Number` objects using a `java.text.NumberFormat`.
The `number` package provides a `NumberStyleFormatter`, `CurrencyStyleFormatter`, and
`PercentStyleFormatter` to format `java.lang.Number` objects using a `java.text.NumberFormat`.
The `datetime` package provides a `DateFormatter` to format `java.util.Date` objects with
a `java.text.DateFormat`. The `datetime.joda` package provides comprehensive datetime
formatting support based on the http://joda-time.sourceforge.net[Joda-Time library].
@@ -1131,7 +1137,6 @@ Consider `DateFormatter` as an example `Formatter` implementation:
dateFormat.setLenient(false);
return dateFormat;
}
}
----
@@ -1142,6 +1147,7 @@ https://jira.spring.io/browse/SPR[jira.spring.io] to contribute.
[[format-CustomFormatAnnotations]]
=== Annotation-driven Formatting
As you will see, field formatting can be configured by field type or annotation. To bind
an Annotation to a formatter, implement AnnotationFormatterFactory:
@@ -1157,7 +1163,6 @@ an Annotation to a formatter, implement AnnotationFormatterFactory:
Printer<?> getPrinter(A annotation, Class<?> fieldType);
Parser<?> getParser(A annotation, Class<?> fieldType);
}
----
@@ -1191,18 +1196,17 @@ specified:
return configureFormatterFrom(annotation, fieldType);
}
private Formatter<Number> configureFormatterFrom(NumberFormat annotation,
Class<?> fieldType) {
private Formatter<Number> configureFormatterFrom(NumberFormat annotation, Class<?> fieldType) {
if (!annotation.pattern().isEmpty()) {
return new NumberFormatter(annotation.pattern());
return new NumberStyleFormatter(annotation.pattern());
} else {
Style style = annotation.style();
if (style == Style.PERCENT) {
return new PercentFormatter();
return new PercentStyleFormatter();
} else if (style == Style.CURRENCY) {
return new CurrencyFormatter();
return new CurrencyStyleFormatter();
} else {
return new NumberFormatter();
return new NumberStyleFormatter();
}
}
}
@@ -1218,13 +1222,13 @@ To trigger formatting, simply annotate fields with @NumberFormat:
@NumberFormat(style=Style.CURRENCY)
private BigDecimal decimal;
}
----
[[format-annotations-api]]
==== Format Annotation API
A portable format annotation API exists in the `org.springframework.format.annotation`
package. Use @NumberFormat to format java.lang.Number fields. Use @DateTimeFormat to
format java.util.Date, java.util.Calendar, java.util.Long, or Joda-Time fields.
@@ -1239,7 +1243,6 @@ The example below uses @DateTimeFormat to format a java.util.Date as a ISO Date
@DateTimeFormat(iso=ISO.DATE)
private Date date;
}
----
@@ -1247,6 +1250,7 @@ The example below uses @DateTimeFormat to format a java.util.Date as a ISO Date
[[format-FormatterRegistry-SPI]]
=== FormatterRegistry SPI
The FormatterRegistry is an SPI for registering formatters and converters.
`FormattingConversionService` is an implementation of FormatterRegistry suitable for
most environments. This implementation may be configured programmatically or
@@ -1270,7 +1274,6 @@ Review the FormatterRegistry SPI below:
void addFormatterForFieldType(Formatter<?> formatter);
void addFormatterForAnnotation(AnnotationFormatterFactory<?, ?> factory);
}
----
@@ -1286,6 +1289,7 @@ these rules once and they are applied whenever formatting is needed.
[[format-FormatterRegistrar-SPI]]
=== FormatterRegistrar SPI
The FormatterRegistrar is an SPI for registering formatters and converters through the
FormatterRegistry:
@@ -1297,7 +1301,6 @@ FormatterRegistry:
public interface FormatterRegistrar {
void registerFormatters(FormatterRegistry registry);
}
----
@@ -1320,6 +1323,7 @@ See <<mvc-config-conversion>> in the Spring MVC chapter.
[[format-configuring-formatting-globaldatetimeformat]]
== Configuring a global date & time format
By default, date and time fields that are not annotated with `@DateTimeFormat` are
converted from strings using the `DateFormat.SHORT` style. If you prefer, you can
change this by defining your own global format.
@@ -1413,6 +1417,7 @@ For XML you should use the `'conversion-service'` attribute of the
[[validation-beanvalidation]]
== Spring Validation
Spring 3 introduces several enhancements to its validation support. First, the JSR-303
Bean Validation API is now fully supported. Second, when used programmatically, Spring's
DataBinder can now validate objects as well as bind to them. Third, Spring MVC now has
@@ -1422,6 +1427,7 @@ support for declaratively validating `@Controller` inputs.
[[validation-beanvalidation-overview]]
=== Overview of the JSR-303 Bean Validation API
JSR-303 standardizes validation constraint declaration and metadata for the Java
platform. Using this API, you annotate domain model properties with declarative
validation constraints and the runtime enforces them. There are a number of built-in
@@ -1451,7 +1457,6 @@ JSR-303 allows you to define declarative validation constraints against such pro
@Min(0)
private int age;
}
----
@@ -1468,6 +1473,7 @@ bean, keep reading.
[[validation-beanvalidation-spring]]
=== Configuring a Bean Validation Provider
Spring provides full support for the Bean Validation API. This includes convenient
support for bootstrapping a JSR-303/JSR-349 Bean Validation provider as a Spring bean.
This allows for a `javax.validation.ValidatorFactory` or `javax.validation.Validator` to
@@ -1489,6 +1495,7 @@ is expected to be present in the classpath and will be detected automatically.
[[validation-beanvalidation-spring-inject]]
==== Injecting a Validator
`LocalValidatorFactoryBean` implements both `javax.validation.ValidatorFactory` and
`javax.validation.Validator`, as well as Spring's
`org.springframework.validation.Validator`. You may inject a reference to either of
@@ -1522,13 +1529,13 @@ the Spring Validation API:
@Autowired
private Validator validator;
}
----
[[validation-beanvalidation-spring-constraints]]
==== Configuring Custom Constraints
Each Bean Validation constraint consists of two parts. First, a `@Constraint` annotation
that declares the constraint and its configurable properties. Second, an implementation
of the `javax.validation.ConstraintValidator` interface that implements the constraint's
@@ -1574,6 +1581,7 @@ As you can see, a ConstraintValidator implementation may have its dependencies
[[validation-beanvalidation-spring-method]]
==== Spring-driven Method Validation
The method validation feature supported by Bean Validation 1.1, and as a custom
extension also by Hibernate Validator 4.3, can be integrated into a Spring context
through a `MethodValidationPostProcessor` bean definition:
@@ -1592,6 +1600,7 @@ for setup details with Hibernate Validator and Bean Validation 1.1 providers.
[[validation-beanvalidation-spring-other]]
==== Additional Configuration Options
The default `LocalValidatorFactoryBean` configuration should prove sufficient for most
cases. There are a number of configuration options for various Bean Validation
constructs, from message interpolation to traversal resolution. See the
@@ -1601,6 +1610,7 @@ constructs, from message interpolation to traversal resolution. See the
[[validation-binder]]
=== Configuring a DataBinder
Since Spring 3, a DataBinder instance can be configured with a Validator. Once
configured, the Validator may be invoked by calling `binder.validate()`. Any validation
Errors are automatically added to the binder's BindingResult.
@@ -1636,4 +1646,3 @@ locally on a DataBinder instance. See <<validation-mvc-configuring>>.
=== Spring MVC 3 Validation
See <<mvc-config-validation>> in the Spring MVC chapter.