Spring formatting API typically allows a UI/GUI application to render objects in formatted string. It also allows the opposite, that is to populate object fields in response to the user formatted input from a UI.
Formatter interface
The Spring formatting API is based on the interface Formatter:
Definition of Formatter(Version: spring-framework 6.1.2) package org.springframework.format;
........
public interface Formatter<T> extends Printer<T>, Parser<T> {}
Formatter interface allows us to convert a bean field of type T to String and vice versa.
Here are the Formatter super interfaces Printer and Parser
Definition of Printer(Version: spring-framework 6.1.2) package org.springframework.format;
........
@FunctionalInterface
public interface Printer<T> {
String print(T object, Locale locale);
}
Definition of Parser(Version: spring-framework 6.1.2) package org.springframework.format;
........
@FunctionalInterface
public interface Parser<T> {
T parse(String text, Locale locale) throws ParseException;
}
Spring provided Formatter implementations
Spring provides various formatter implementations in the following packages:
The above formatter may be registered implicitly by Spring depending on what context we are using.
Converter vs Formatter
Spring Converter API provides general purpose type conversion system. Converters do not address customized formatted field values rendering. Formatter API does that. Formatters can also localize String values while formatting e.g. rendering Date/LocalDate etc per client locale.
ConversionService and Formatters
Other than invoking converters, ConversionService may invoke formatters as well. ConversionService does not define any specific methods related to formatting though, instead a Formatter may be implicitly invoked on ConversionService#convert() method call.
In a core Spring application we have to use ConversionService implementations like FormattingConversionService or DefaultFormattingConversionService. Both these implementations also implement FormatterRegistry interface which allows for user defined formatters to be registered:
Definition of FormatterRegistry(Version: spring-framework 6.1.2) package org.springframework.format;
........
public interface FormatterRegistry extends ConverterRegistry {
void addPrinter(Printer<?> printer);
void addParser(Parser<?> parser);
void addFormatter(Formatter<?> formatter);
void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter);
void addFormatterForFieldType(
Class<?> fieldType, Printer<?> printer, Parser<?> parser);
void addFormatterForFieldAnnotation(
AnnotationFormatterFactory<? extends Annotation>
annotationFormatterFactory);
}
By default, FormattingConversionService does not register any of Spring provided formatters (as listed above).
DefaultFormattingConversionService registers most of those formatters by default. Here's a simple example:
package com.logicbig.example;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.DefaultFormattingConversionService;
import java.time.Instant;
import java.time.LocalDate;
public class DefaultFormattingConversionServiceExample {
public static void main (String[] args) {
ConversionService service =
new DefaultFormattingConversionService();
//String to Instant
Instant instant = service.convert("2016-11-15T01:12:05.695Z", Instant.class);
System.out.println(instant);
//Instant to String
String convert = service.convert(instant, String.class);
System.out.println(convert);
LocalDate localDate = service.convert("11/13/16", LocalDate.class);
System.out.println(localDate);
}
}
Output2016-11-15T01:12:05.695Z 2016-11-15T01:12:05.695Z 2016-11-13
The above service.convert() calls use InstantFormatter (we are doing both sides formatting i.e. Instant to String and vice versa) and TemporalAccessorParser respectively.
Example ProjectDependencies and Technologies Used: - spring-context 6.1.2 (Spring Context)
Version Compatibility: 4.0.0.RELEASE - 6.1.2 Version compatibilities of spring-context with this example: Versions in green have been tested.
- JDK 17
- Maven 3.8.1
|