|
|
@ -362,10 +362,9 @@ the knowledge of how to convert properties to the desired type. Read more about |
|
|
|
A couple of examples where property editing is used in Spring: |
|
|
|
A couple of examples where property editing is used in Spring: |
|
|
|
|
|
|
|
|
|
|
|
* __setting properties on beans__ is done using `PropertyEditors`. When mentioning |
|
|
|
* __setting properties on beans__ is done using `PropertyEditors`. When mentioning |
|
|
|
`java.lang.String` as the value of a property of some bean you're declaring in XML |
|
|
|
`String` as the value of a property of some bean you're declaring in XML file, |
|
|
|
file, Spring will (if the setter of the corresponding property has a |
|
|
|
Spring will (if the setter of the corresponding property has `Class` parameter) |
|
|
|
`Class`-parameter) use the `ClassEditor` to try to resolve the parameter to a `Class` |
|
|
|
use the `ClassEditor` to try to resolve the parameter to a `Class` object. |
|
|
|
object. |
|
|
|
|
|
|
|
* __parsing HTTP request parameters__ in Spring's MVC framework is done using all kinds |
|
|
|
* __parsing HTTP request parameters__ in Spring's MVC framework is done using all kinds |
|
|
|
of `PropertyEditors` that you can manually bind in all subclasses of the |
|
|
|
of `PropertyEditors` that you can manually bind in all subclasses of the |
|
|
|
`CommandController`. |
|
|
|
`CommandController`. |
|
|
@ -761,9 +760,9 @@ Consider `StringToInteger` as an example for a typical `Converter` implementatio |
|
|
|
[[core-convert-ConverterFactory-SPI]] |
|
|
|
[[core-convert-ConverterFactory-SPI]] |
|
|
|
=== ConverterFactory |
|
|
|
=== ConverterFactory |
|
|
|
|
|
|
|
|
|
|
|
When you need to centralize the conversion logic for an entire class hierarchy, for |
|
|
|
When you need to centralize the conversion logic for an entire class hierarchy |
|
|
|
example, when converting from String to java.lang.Enum objects, implement |
|
|
|
(for example, when converting from `String` to `Enum` objects), you can implement |
|
|
|
`ConverterFactory`: |
|
|
|
`ConverterFactory`, as the following example shows: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -777,10 +776,10 @@ example, when converting from String to java.lang.Enum objects, implement |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
Parameterize S to be the type you are converting from and R to be the base type defining |
|
|
|
Parameterize S to be the type you are converting from and R to be the base type defining |
|
|
|
the __range__ of classes you can convert to. Then implement getConverter(Class<T>), |
|
|
|
the __range__ of classes you can convert to. Then implement `getConverter(Class<T>)`, |
|
|
|
where T is a subclass of R. |
|
|
|
where T is a subclass of R. |
|
|
|
|
|
|
|
|
|
|
|
Consider the `StringToEnum` ConverterFactory as an example: |
|
|
|
Consider the `StringToEnumConverterFactory` as an example: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -813,12 +812,13 @@ Consider the `StringToEnum` ConverterFactory as an example: |
|
|
|
[[core-convert-GenericConverter-SPI]] |
|
|
|
[[core-convert-GenericConverter-SPI]] |
|
|
|
=== GenericConverter |
|
|
|
=== GenericConverter |
|
|
|
|
|
|
|
|
|
|
|
When you require a sophisticated Converter implementation, consider the GenericConverter |
|
|
|
When you require a sophisticated `Converter` implementation, consider using the |
|
|
|
interface. With a more flexible but less strongly typed signature, a GenericConverter |
|
|
|
`GenericConverter` interface. With a more flexible but less strongly typed signature |
|
|
|
supports converting between multiple source and target types. In addition, a |
|
|
|
than `Converter`, a `GenericConverter` supports converting between multiple source and |
|
|
|
GenericConverter makes available source and target field context you can use when |
|
|
|
target types. In addition, a `GenericConverter` makes available source and target field |
|
|
|
implementing your conversion logic. Such context allows a type conversion to be driven |
|
|
|
context that you can use when you implement your conversion logic. Such context lets a |
|
|
|
by a field annotation, or generic information declared on a field signature. |
|
|
|
type conversion be driven by a field annotation or by generic information declared on a |
|
|
|
|
|
|
|
field signature. The following listing shows the interface definition of `GenericConverter`: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -833,22 +833,22 @@ by a field annotation, or generic information declared on a field signature. |
|
|
|
} |
|
|
|
} |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
To implement a GenericConverter, have getConvertibleTypes() return the supported |
|
|
|
To implement a `GenericConverter`, have `getConvertibleTypes()` return the supported |
|
|
|
source->target type pairs. Then implement convert(Object, TypeDescriptor, |
|
|
|
source->target type pairs. Then implement `convert(Object, TypeDescriptor, |
|
|
|
TypeDescriptor) to implement your conversion logic. The source TypeDescriptor provides |
|
|
|
TypeDescriptor)` to contain your conversion logic. The source `TypeDescriptor` provides |
|
|
|
access to the source field holding the value being converted. The target TypeDescriptor |
|
|
|
access to the source field that holds the value being converted. The target `TypeDescriptor` |
|
|
|
provides access to the target field where the converted value will be set. |
|
|
|
provides access to the target field where the converted value is to be set. |
|
|
|
|
|
|
|
|
|
|
|
A good example of a GenericConverter is a converter that converts between a Java Array |
|
|
|
A good example of a `GenericConverter` is a converter that converts between a Java array |
|
|
|
and a Collection. Such an ArrayToCollectionConverter introspects the field that declares |
|
|
|
and a collection. Such an `ArrayToCollectionConverter` introspects the field that declares |
|
|
|
the target Collection type to resolve the Collection's element type. This allows each |
|
|
|
the target collection type to resolve the collection's element type. This lets each |
|
|
|
element in the source array to be converted to the Collection element type before the |
|
|
|
element in the source array be converted to the collection element type before the |
|
|
|
Collection is set on the target field. |
|
|
|
collection is set on the target field. |
|
|
|
|
|
|
|
|
|
|
|
[NOTE] |
|
|
|
[NOTE] |
|
|
|
==== |
|
|
|
==== |
|
|
|
Because GenericConverter is a more complex SPI interface, only use it when you need it. |
|
|
|
Because `GenericConverter` is a more complex SPI interface, only use it when you need it. |
|
|
|
Favor Converter or ConverterFactory for basic type conversion needs. |
|
|
|
Favor `Converter` or `ConverterFactory` for basic type conversion needs. |
|
|
|
==== |
|
|
|
==== |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1044,11 +1044,11 @@ general __core.convert__ Converter SPI does not address such __formatting__ requ |
|
|
|
directly. To directly address them, Spring 3 introduces a convenient Formatter SPI that |
|
|
|
directly. To directly address them, Spring 3 introduces a convenient Formatter SPI that |
|
|
|
provides a simple and robust alternative to PropertyEditors for client environments. |
|
|
|
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 |
|
|
|
In general, you can use the `Converter` SPI when you need to implement general-purpose type |
|
|
|
conversion logic; for example, for converting between a java.util.Date and and |
|
|
|
conversion logic -- for example, for converting between a `java.util.Date` and a `Long`. |
|
|
|
java.lang.Long. Use the Formatter SPI when you're working in a client environment, such |
|
|
|
You can use the `Formatter` SPI when you work in a client environment (such as a web |
|
|
|
as a web application, and need to parse and print localized field values. The |
|
|
|
application) and need to parse and print localized field values. The `ConversionService` |
|
|
|
ConversionService provides a unified type conversion API for both SPIs. |
|
|
|
provides a unified type conversion API for both SPIs. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1088,22 +1088,22 @@ Where Formatter extends from the Printer and Parser building-block interfaces: |
|
|
|
} |
|
|
|
} |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
To create your own Formatter, simply implement the Formatter interface above. |
|
|
|
To create your own `Formatter`, implement the `Formatter` interface shown earlier. |
|
|
|
Parameterize T to be the type of object you wish to format, for example, |
|
|
|
Parameterize `T` to be the type of object you wish to format -- for example, |
|
|
|
`java.util.Date`. Implement the `print()` operation to print an instance of T for |
|
|
|
`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 |
|
|
|
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 |
|
|
|
`T` from the formatted representation returned from the client locale. Your `Formatter` |
|
|
|
should throw a ParseException or IllegalArgumentException if a parse attempt fails. Take |
|
|
|
should throw a `ParseException` or an `IllegalArgumentException` if a parse attempt fails. Take |
|
|
|
care to ensure your Formatter implementation is thread-safe. |
|
|
|
care to ensure that your `Formatter` implementation is thread-safe. |
|
|
|
|
|
|
|
|
|
|
|
Several Formatter implementations are provided in `format` subpackages as a convenience. |
|
|
|
The `format` subpackages provide several `Formatter` implementations as a convenience. |
|
|
|
The `number` package provides a `NumberStyleFormatter`, `CurrencyStyleFormatter`, and |
|
|
|
The `number` package provides `NumberStyleFormatter`, `CurrencyStyleFormatter`, and |
|
|
|
`PercentStyleFormatter` to format `java.lang.Number` objects using a `java.text.NumberFormat`. |
|
|
|
`PercentStyleFormatter` to format `Number` objects that use a `java.text.NumberFormat`. |
|
|
|
The `datetime` package provides a `DateFormatter` to format `java.util.Date` objects with |
|
|
|
The `datetime` package provides a `DateFormatter` to format `java.util.Date` objects with |
|
|
|
a `java.text.DateFormat`. The `datetime.joda` package provides comprehensive datetime |
|
|
|
a `java.text.DateFormat`. The `datetime.joda` package provides comprehensive datetime |
|
|
|
formatting support based on the http://joda-time.sourceforge.net[Joda-Time library]. |
|
|
|
formatting support based on the http://joda-time.sourceforge.net[Joda-Time library]. |
|
|
|
|
|
|
|
|
|
|
|
Consider `DateFormatter` as an example `Formatter` implementation: |
|
|
|
The following `DateFormatter` is an example `Formatter` implementation: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -1230,10 +1230,11 @@ To trigger formatting, simply annotate fields with @NumberFormat: |
|
|
|
==== Format Annotation API |
|
|
|
==== Format Annotation API |
|
|
|
|
|
|
|
|
|
|
|
A portable format annotation API exists in the `org.springframework.format.annotation` |
|
|
|
A portable format annotation API exists in the `org.springframework.format.annotation` |
|
|
|
package. Use @NumberFormat to format java.lang.Number fields. Use @DateTimeFormat to |
|
|
|
package. You can use `@NumberFormat` to format `Number` fields such as `Double` and |
|
|
|
format java.util.Date, java.util.Calendar, java.util.Long, or Joda-Time fields. |
|
|
|
`Long`, and `@DateTimeFormat` to format `java.util.Date`, `java.util.Calendar`, `Long` |
|
|
|
|
|
|
|
(for millisecond timestamps) as well as JSR-310 `java.time` and Joda-Time value types. |
|
|
|
|
|
|
|
|
|
|
|
The example below uses @DateTimeFormat to format a java.util.Date as a ISO Date |
|
|
|
The following example uses `@DateTimeFormat` to format a `java.util.Date` as an ISO Date |
|
|
|
(yyyy-MM-dd): |
|
|
|
(yyyy-MM-dd): |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|