1.FormatterRegistry接口
Spring框架提供了一个FormatterRegistry接口,用于注册自定义的Formatter和Converter,以支持更灵活的数据格式化和转换。通过实现Formatter或Converter接口,我们可以自定义数据的格式化和转换规则,并将其注册到FormatterRegistry中。
下面是一个使用addFormatters方法注册自定义Formatter的示例:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
// 注册自定义的DateFormatter
registry.addFormatter(new DateFormatter("yyyy-MM-dd"));
// 注册自定义的StringToEnumConverter
registry.addConverter(new StringToEnumConverter());
}
}
我们定义了一个WebConfig类,并实现了WebMvcConfigurer接口。通过重写addFormatters方法,我们可以访问FormatterRegistry对象,并使用addFormatter和addConverter方法注册自定义的Formatter和Converter。
- 注册自定义的DateFormatter:
- 我们创建了一个DateFormatter对象,并指定了日期格式为"yyyy-MM-dd"。
- 通过registry.addFormatter方法,将DateFormatter注册到FormatterRegistry中。
- 这样,当Spring框架需要格式化或解析日期字符串时,就会使用我们自定义的DateFormatter。
- 注册自定义的StringToEnumConverter:
- 我们创建了一个StringToEnumConverter对象,用于将字符串转换为枚举类型。
- 通过registry.addConverter方法,将StringToEnumConverter注册到FormatterRegistry中。
- 这样,当Spring框架需要将字符串转换为枚举类型时,就会使用我们自定义的StringToEnumConverter。
一旦我们注册了自定义的Formatter和Converter,Spring框架就会在需要进行数据格式化和转换时自动使用它们。例如,当我们使用@RequestParam注解接收日期参数时,Spring会使用我们注册的DateFormatter来解析日期字符串。
2.Converter
Converter是一个用于在不同数据类型之间进行转换的工具类或接口。它的主要作用是将一种数据类型转换为另一种数据类型,以满足不同场景下的需求。在Java中,Converter通常用于以下几个方面:
- 数据绑定:在将数据从一个对象绑定到另一个对象时,如果两个对象的属性类型不同,可以使用Converter进行类型转换。例如,将字符串类型的属性转换为整数类型。
假设我们有一个User类,其中有一个age属性,类型为Integer。但是在前端表单提交数据时,age是以字符串的形式提交的。这时,我们可以使用Converter将字符串转换为Integer类型。public class StringToIntegerConverter implements Converter<String, Integer> { @Override public Integer convert(String source) { return Integer.valueOf(source); } }
- 数据格式化:Converter可以将数据格式化为特定的字符串表示形式,或者将字符串解析为特定的数据类型。例如,将日期对象转换为指定格式的字符串,或将字符串解析为日期对象。
public class StringToDateConverter implements Converter<String, Date> { private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); @Override public Date convert(String source) { try { return DATE_FORMAT.parse(source); } catch (ParseException e) { throw new IllegalArgumentException("无效的日期格式: " + source); } } }
- 数据校验:Converter可以在转换数据的同时进行数据校验,确保转换后的数据符合特定的约束条件。例如,将字符串转换为整数时,可以检查字符串是否为有效的整数格式。
public class GradeConverter implements Converter<String, Double> { @Override public Double convert(String source) { if (source.equals("A+")) { return 4.0; } else if (source.equals("A")) { return 4.0; } else if (source.equals("B+")) { return 3.5; } else if (source.equals("B")) { return 3.0; } else { throw new IllegalArgumentException("无效的分数: " + source); } } }
- 国际化支持:Converter可以根据不同的语言环境对数据进行转换和格式化,以支持国际化和本地化。例如,将数字格式化为不同国家的货币格式。
public class CurrencyConverter implements Converter<Double, String> { private final NumberFormat currencyFormat; public CurrencyConverter(Locale locale) { currencyFormat = NumberFormat.getCurrencyInstance(locale); } @Override public String convert(Double source) { return currencyFormat.format(source); } }
3.Converterfactory
Spring框架提供了ConverterFactory接口,用于创建一组相关的Converter实例。当我们需要将多个相似的类型进行转换时,可以使用ConverterFactory来生成对应的Converter实例,而不需要为每个类型单独创建Converter。
ConverterFactory接口定义如下:
public interface ConverterFactory<S, R> {
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
其中,S表示源类型,R表示目标类型的基类或接口。getConverter方法接受一个目标类型的Class对象,并返回一个能够将源类型转换为目标类型的Converter实例。
public class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
@Override
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
return new StringToEnumConverter<>(targetType);
}
private static class StringToEnumConverter<T extends Enum> implements Converter<String, T> {
private final Class<T> enumType;
public StringToEnumConverter(Class<T> enumType) {
this.enumType = enumType;
}
@Override
public T convert(String source) {
return Enum.valueOf(enumType, source.toUpperCase());
}
}
}
我们定义了一个StringToEnumConverterFactory类,它实现了ConverterFactory接口。
- getConverter方法:
- 接受一个目标枚举类型的Class对象作为参数。
- 返回一个StringToEnumConverter实例,该实例能够将字符串转换为指定的枚举类型。
- StringToEnumConverter类:
- 是一个内部类,实现了Converter接口。
- 构造函数接受一个目标枚举类型的Class对象,并将其存储在enumType字段中。
- convert方法将字符串转换为对应的枚举值,使用Enum.valueOf方法实现转换。
使用ConverterFactory的好处是,我们只需要定义一个工厂类,就可以生成多个相关的Converter实例。在上面的示例中,StringToEnumConverterFactory可以生成任意枚举类型的Converter,而不需要为每个枚举类型单独创建Converter。要将ConverterFactory注册到Spring框架中,可以使用FormatterRegistry的addConverterFactory方法:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(new StringToEnumConverterFactory());
}
}
通过注册StringToEnumConverterFactory,Spring框架就可以在需要将字符串转换为枚举类型时,自动使用相应的Converter实例进行转换。