Close

Spring - Field Formatting

[Last Updated: Dec 22, 2023]

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);
  }
}

Output

2016-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 Project

Dependencies and Technologies Used:

  • spring-context 6.1.2 (Spring Context)
     Version Compatibility: 4.0.0.RELEASE - 6.1.2Version List
    ×

    Version compatibilities of spring-context with this example:

    • 4.0.0.RELEASE
    • 4.0.1.RELEASE
    • 4.0.2.RELEASE
    • 4.0.3.RELEASE
    • 4.0.4.RELEASE
    • 4.0.5.RELEASE
    • 4.0.6.RELEASE
    • 4.0.7.RELEASE
    • 4.0.8.RELEASE
    • 4.0.9.RELEASE
    • 4.1.0.RELEASE
    • 4.1.1.RELEASE
    • 4.1.2.RELEASE
    • 4.1.3.RELEASE
    • 4.1.4.RELEASE
    • 4.1.5.RELEASE
    • 4.1.6.RELEASE
    • 4.1.7.RELEASE
    • 4.1.8.RELEASE
    • 4.1.9.RELEASE
    • 4.2.0.RELEASE
    • 4.2.1.RELEASE
    • 4.2.2.RELEASE
    • 4.2.3.RELEASE
    • 4.2.4.RELEASE
    • 4.2.5.RELEASE
    • 4.2.6.RELEASE
    • 4.2.7.RELEASE
    • 4.2.8.RELEASE
    • 4.2.9.RELEASE
    • 4.3.0.RELEASE
    • 4.3.1.RELEASE
    • 4.3.2.RELEASE
    • 4.3.3.RELEASE
    • 4.3.4.RELEASE
    • 4.3.5.RELEASE
    • 4.3.6.RELEASE
    • 4.3.7.RELEASE
    • 4.3.8.RELEASE
    • 4.3.9.RELEASE
    • 4.3.10.RELEASE
    • 4.3.11.RELEASE
    • 4.3.12.RELEASE
    • 4.3.13.RELEASE
    • 4.3.14.RELEASE
    • 4.3.15.RELEASE
    • 4.3.16.RELEASE
    • 4.3.17.RELEASE
    • 4.3.18.RELEASE
    • 4.3.19.RELEASE
    • 4.3.20.RELEASE
    • 4.3.21.RELEASE
    • 4.3.22.RELEASE
    • 4.3.23.RELEASE
    • 4.3.24.RELEASE
    • 4.3.25.RELEASE
    • 4.3.26.RELEASE
    • 4.3.27.RELEASE
    • 4.3.28.RELEASE
    • 4.3.29.RELEASE
    • 4.3.30.RELEASE
    • 5.0.0.RELEASE
    • 5.0.1.RELEASE
    • 5.0.2.RELEASE
    • 5.0.3.RELEASE
    • 5.0.4.RELEASE
    • 5.0.5.RELEASE
    • 5.0.6.RELEASE
    • 5.0.7.RELEASE
    • 5.0.8.RELEASE
    • 5.0.9.RELEASE
    • 5.0.10.RELEASE
    • 5.0.11.RELEASE
    • 5.0.12.RELEASE
    • 5.0.13.RELEASE
    • 5.0.14.RELEASE
    • 5.0.15.RELEASE
    • 5.0.16.RELEASE
    • 5.0.17.RELEASE
    • 5.0.18.RELEASE
    • 5.0.19.RELEASE
    • 5.0.20.RELEASE
    • 5.1.0.RELEASE
    • 5.1.1.RELEASE
    • 5.1.2.RELEASE
    • 5.1.3.RELEASE
    • 5.1.4.RELEASE
    • 5.1.5.RELEASE
    • 5.1.6.RELEASE
    • 5.1.7.RELEASE
    • 5.1.8.RELEASE
    • 5.1.9.RELEASE
    • 5.1.10.RELEASE
    • 5.1.11.RELEASE
    • 5.1.12.RELEASE
    • 5.1.13.RELEASE
    • 5.1.14.RELEASE
    • 5.1.15.RELEASE
    • 5.1.16.RELEASE
    • 5.1.17.RELEASE
    • 5.1.18.RELEASE
    • 5.1.19.RELEASE
    • 5.1.20.RELEASE
    • 5.2.0.RELEASE
    • 5.2.1.RELEASE
    • 5.2.2.RELEASE
    • 5.2.3.RELEASE
    • 5.2.4.RELEASE
    • 5.2.5.RELEASE
    • 5.2.6.RELEASE
    • 5.2.7.RELEASE
    • 5.2.8.RELEASE
    • 5.2.9.RELEASE
    • 5.2.10.RELEASE
    • 5.2.11.RELEASE
    • 5.2.12.RELEASE
    • 5.2.13.RELEASE
    • 5.2.14.RELEASE
    • 5.2.15.RELEASE
    • 5.2.16.RELEASE
    • 5.2.17.RELEASE
    • 5.2.18.RELEASE
    • 5.2.19.RELEASE
    • 5.2.20.RELEASE
    • 5.2.21.RELEASE
    • 5.2.22.RELEASE
    • 5.2.23.RELEASE
    • 5.2.24.RELEASE
    • 5.2.25.RELEASE
    • 5.3.0
    • 5.3.1
    • 5.3.2
    • 5.3.3
    • 5.3.4
    • 5.3.5
    • 5.3.6
    • 5.3.7
    • 5.3.8
    • 5.3.9
    • 5.3.10
    • 5.3.11
    • 5.3.12
    • 5.3.13
    • 5.3.14
    • 5.3.15
    • 5.3.16
    • 5.3.17
    • 5.3.18
    • 5.3.19
    • 5.3.20
    • 5.3.21
    • 5.3.22
    • 5.3.23
    • 5.3.24
    • 5.3.25
    • 5.3.26
    • 5.3.27
    • 5.3.28
    • 5.3.29
    • 5.3.30
    • 5.3.31
    • Compatible Java Version: 17+
    • 6.0.0
    • 6.0.1
    • 6.0.2
    • 6.0.3
    • 6.0.4
    • 6.0.5
    • 6.0.6
    • 6.0.7
    • 6.0.8
    • 6.0.9
    • 6.0.10
    • 6.0.11
    • 6.0.12
    • 6.0.13
    • 6.0.14
    • 6.0.15
    • 6.1.0
    • 6.1.1
    • 6.1.2

    Versions in green have been tested.

  • JDK 17
  • Maven 3.8.1

Spring Formatter Example Select All Download
  • spring-core-formatting-getting-started
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • DefaultFormattingConversionServiceExample.java

    See Also