JAVA Spring
Spring Type Conversion & Formatter
neal89
2025. 4. 11. 14:51
1. Why Type Conversion Matters in Spring
Spring often needs to convert data types between String ↔ Object, especially in:
- @RequestParam, @PathVariable, @ModelAttribute
- YAML (@Value)
- View rendering (Thymeleaf)
- Form input/output
2. Converter Interface
public interface Converter<S, T> {
T convert(S source);
}
- Generic, bidirectional type conversion (e.g. String ↔ Integer, IpPort ↔ String)
- Used programmatically or injected into Spring's type system
3. ConversionService
conversionService.convert("10", Integer.class); // returns 10
- Central API for runtime type conversion
- Main implementation: DefaultConversionService
✅ ISP (Interface Segregation Principle)
Clients should not depend on methods they do not use.
- DefaultConversionService implements both:
- ConversionService: For type conversion
- ConverterRegistry: For registering converters
This design separates usage from registration, following ISP.
4. Registering Converters via WebMvcConfigurer
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToIpPortConverter());
registry.addConverter(new IpPortToStringConverter());
}
}
These converters are then automatically applied in @RequestParam, @PathVariable, etc.
5. Formatter Interface
public interface Formatter<T> extends Printer<T>, Parser<T> {
String print(T object, Locale locale);
T parse(String text, Locale locale);
}
- Specialization of Converter for String ↔ Object with Locale support
- Used for formatting numbers, dates, etc.
- Example: "1,000" ↔ 1000
6. Registering Formatters: FormattingConversionService
⚠️ Note: ConversionService cannot accept formatters.
✅ Use FormattingConversionService (or its subclass DefaultFormattingConversionService) to register formatters.
conversionService.addFormatter(new MyNumberFormatter());
- Internally, it adapts Formatter to Converter using the Adapter Pattern.
- This allows uniform access to all converters/formatters through the ConversionService interface.
7. Built-in Formatter Annotations
Annotation Description
@NumberFormat | Controls number formatting (e.g., #,###) |
@DateTimeFormat | Controls date/time formatting |
Example:
@NumberFormat(pattern = "###,###")
private Integer number;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;
8. Thymeleaf & Conversion
- ${object} → plain output
- ${{object}} → applies ConversionService for formatting
Works for both converters and formatters.
9. ❗ Not Applied: HttpMessageConverter
Spring's ConversionService is not used in:
- JSON (de)serialization via HttpMessageConverter (uses Jackson/Gson)
- To customize JSON formats (e.g., for numbers or dates), configure the JSON library directly.
✅ Final Takeaway
Concept | Use Case |
Converter | General-purpose conversion between any two types |
Formatter | Locale-aware String ↔ Object formatting |
ConversionService | Unified API to perform conversions |
FormattingConversionService | Registers both converters and formatters (uses adapter pattern) |
WebMvcConfigurer | Hook to register your converters/formatters in Spring MVC |
@NumberFormat / @DateTimeFormat | Field-level formatting in models |
Not Used In | JSON serialization (handled by Jackson, not ConversionService) |