1.内置Format
可以参考此篇文章
https://www.jianshu.com/p/c8f16cab35e1
2. Formatter
Parser负责输入,Printer负责输出
具体实现如下图:
可以跟以上一一对应
- DateFormatter对应DateFormat
- PercentStyleFormatter对应DecimalFormat,用于百分比格式化
- NumberStyleFormatter对应数字格式化
- CurrencyStyleFormatter对应货币类型数字格式化
2.1 demo示例
使用接口非常一致,都是parse方法和print方法
public class CurrencyStyleFormatterTests {
private final CurrencyStyleFormatter formatter = new CurrencyStyleFormatter();
@Test
public void formatValue() {
assertEquals("$23.00", formatter.print(new BigDecimal("23"), Locale.US));
}
@Test
public void parseValue() throws ParseException {
assertEquals(new BigDecimal("23.56"), formatter.parse("$23.56", Locale.US));
}
}
public class NumberStyleFormatterTests {
private final NumberStyleFormatter formatter = new NumberStyleFormatter();
@Test
public void formatValue() {
assertEquals("23.56", formatter.print(new BigDecimal("23.56"), Locale.US));
}
@Test
public void parseValue() throws ParseException {
assertEquals(new BigDecimal("23.56"), formatter.parse("23.56", Locale.US));
}
}
public class PercentStyleFormatterTests {
private final PercentStyleFormatter formatter = new PercentStyleFormatter();
@Test
public void formatValue() {
assertEquals("23%", formatter.print(new BigDecimal(".23"), Locale.US));
}
@Test
public void parseValue() throws ParseException {
assertEquals(new BigDecimal(".2356"), formatter.parse("23.56%", Locale.US));
}
}
public class DateFormatterTests {
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
@Test
public void shouldPrintAndParseDefault() throws Exception {
DateFormatter formatter = new DateFormatter();
formatter.setTimeZone(UTC);
Date date = getDate(2009, Calendar.JUNE, 1);
assertThat(formatter.print(date, Locale.US), is("Jun 1, 2009"));
assertThat(formatter.parse("Jun 1, 2009", Locale.US), is(date));
}
}
3.FormattingConversionService
FormattingConversionService继承自GenericConversionService,扩展自Conveter体系,t
3.1 FormatterRegistry
提供添加Foramtter接口, FormattingConversionService其内部实现还是转换为GenericConverter
3.2 示例
public class FormattingConversionServiceTests {
private FormattingConversionService formattingService;
@Before
public void setUp() {
formattingService = new FormattingConversionService();
DefaultConversionService.addDefaultConverters(formattingService);
LocaleContextHolder.setLocale(Locale.US);
}
@After
public void tearDown() {
LocaleContextHolder.setLocale(null);
}
@Test
public void formatFieldForTypeWithFormatter() throws ParseException {
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
String formatted = formattingService.convert(3, String.class);
assertEquals("3", formatted);
Integer i = formattingService.convert("3", Integer.class);
assertEquals(new Integer(3), i);
}
}
4.FormattingConversionServiceFactoryBean
同样FormattingConversionService也有一个FactoryBean,也可以通过此方式来初始化FormattingConversionService并添加formatters
@Test
public void testCustomFormatter() throws Exception {
FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean();
Set
5.自定义Formatter
5.1 实现Formatter接口
使用方式与ConversionService接口一致
private static class TestBean {
@NumberFormat(pattern = "##,00")
private double pattern;
@SpecialInt("aliased")
private int specialInt;
public int getSpecialInt() {
return specialInt;
}
public void setSpecialInt(int field) {
this.specialInt = field;
}
}
private static class TestBeanFormatter implements Formatter {
@Override
public String print(TestBean object, Locale locale) {
return String.valueOf(object.getSpecialInt());
}
@Override
public TestBean parse(String text, Locale locale) throws ParseException {
TestBean object = new TestBean();
object.setSpecialInt(Integer.parseInt(text));
return object;
}
}
@Test
public void testCustomFormatter() throws Exception {
...
TestBean testBean = fcs.convert("5", TestBean.class);
assertEquals(5, testBean.getSpecialInt());
assertEquals("5", fcs.convert(testBean, String.class));
}
5.2 AnnotationFormatterFactory
内置支持的注解有NumberFormat和DateTimeFormat
通过TypeDescriptor参数的convert方法来进行传递转换
private static class SpecialIntAnnotationFormatterFactory implements AnnotationFormatterFactory {
private final Set> fieldTypes = new HashSet<>(1);
public SpecialIntAnnotationFormatterFactory() {
fieldTypes.add(Integer.class);
}
@Override
public Set> getFieldTypes() {
return fieldTypes;
}
@Override
public Printer> getPrinter(SpecialInt annotation, Class> fieldType) {
assertEquals("aliased", annotation.value());
assertEquals("aliased", annotation.alias());
return new Printer() {
@Override
public String print(Integer object, Locale locale) {
return ":" + object.toString();
}
};
}
@Override
public Parser> getParser(SpecialInt annotation, Class> fieldType) {
assertEquals("aliased", annotation.value());
assertEquals("aliased", annotation.alias());
return new Parser() {
@Override
public Integer parse(String text, Locale locale) throws ParseException {
return Integer.parseInt(text.substring(1));
}
};
}
}
@Test
public void testCustomFormatter() throws Exception {
...
TypeDescriptor descriptor = new TypeDescriptor(TestBean.class.getDeclaredField("specialInt"));
Object value = fcs.convert(":5", TypeDescriptor.valueOf(String.class), descriptor);
assertEquals(5, value);
value = fcs.convert(5, descriptor, TypeDescriptor.valueOf(String.class));
assertEquals(":5", value);
}
参考:
http://jinnianshilongnian.iteye.com/blog/1729739