Spring中字段格式化的使用小結(jié)
Spring提供的一個(gè)core.convert包 是一個(gè)通用類型轉(zhuǎn)換系統(tǒng)。它提供了統(tǒng)一的 ConversionService API和強(qiáng)類型的Converter SPI,用于實(shí)現(xiàn)從一種類型到另一種類型的轉(zhuǎn)換邏輯。Spring容器使用這個(gè)系統(tǒng)綁定bean屬性值。此外,Spring Expression Language (SpEL)和DataBinder都使用這個(gè)系統(tǒng)來(lái)綁定字段值。例如,當(dāng)SpEL需要將Short強(qiáng)制轉(zhuǎn)換為L(zhǎng)ong來(lái)完成表達(dá)式時(shí)。setValue(對(duì)象bean,對(duì)象值)嘗試,核心。轉(zhuǎn)換系統(tǒng)執(zhí)行強(qiáng)制轉(zhuǎn)換。
現(xiàn)在考慮典型客戶端環(huán)境(例如web或桌面應(yīng)用程序)的類型轉(zhuǎn)換需求。在這種環(huán)境中,通常從String轉(zhuǎn)換為支持客戶端回發(fā)過(guò)程,并返回String以支持視圖呈現(xiàn)過(guò)程。此外,你經(jīng)常需要本地化String值。更一般的core.convert Converter SPI不能直接解決這些格式要求。為了直接解決這些問(wèn)題,Spring 3引入了一個(gè)方便的Formatter SPI,它為客戶端環(huán)境提供了PropertyEditor實(shí)現(xiàn)的一個(gè)簡(jiǎn)單而健壯的替代方案。
通常,當(dāng)你需要實(shí)現(xiàn)通用類型轉(zhuǎn)換邏輯時(shí),你可以使用Converter SPI,例如,用于java.util.Date和Long之間的轉(zhuǎn)換。當(dāng)你在客戶端環(huán)境(例如web應(yīng)用程序)中工作并需要解析和打印本地化的字段值時(shí),你可以使用Formatter SPI。ConversionService為這兩個(gè)spi提供了統(tǒng)一的類型轉(zhuǎn)換API。
1、Formatter SPI
實(shí)現(xiàn)字段格式化邏輯的Formatter SPI是簡(jiǎn)單且強(qiáng)類型的。下面的清單顯示了Formatter接口定義:
package org.springframework.format; public interface Formatter<T> extends Printer<T>, Parser<T> { }
Formatter繼承自Printer和Parser接口。
@FunctionalInterface public interface Printer<T> { String print(T object, Locale locale); } @FunctionalInterface public interface Parser<T> { T parse(String text, Locale locale) throws ParseException; }
默認(rèn)情況下Spring容器提供了幾個(gè)Formatter實(shí)現(xiàn)。數(shù)字包提供了NumberStyleFormatter、CurrencyStyleFormatter和PercentStyleFormatter來(lái)格式化使用java.text.NumberFormat的number對(duì)象。datetime包提供了一個(gè)DateFormatter來(lái)用java.text.DateFormat格式化 java.util.Date對(duì)象。
自定義Formatter。
public class StringToNumberFormatter implements Formatter<Number> { @Override public String print(Number object, Locale locale) { return "結(jié)果是:" + object.toString(); } @Override public Number parse(String text, Locale locale) throws ParseException { return NumberFormat.getInstance().parse(text); } }
如何使用?我們可以通過(guò)FormattingConversionService 轉(zhuǎn)換服務(wù)進(jìn)行添加自定義的格式化類。
FormattingConversionService fcs = new FormattingConversionService(); // 默認(rèn)如果不添加自定義的格式化類,那么程序運(yùn)行將會(huì)報(bào)錯(cuò) fcs.addFormatterForFieldType(Number.class, new StringToNumberFormatter()); Number number = fcs.convert("100.5", Number.class); System.out.println(number);
查看源碼:
public class FormattingConversionService extends GenericConversionService implements FormatterRegistry, EmbeddedValueResolverAware { public void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter) { addConverter(new PrinterConverter(fieldType, formatter, this)); addConverter(new ParserConverter(fieldType, formatter, this)); } private static class PrinterConverter implements GenericConverter {} private static class ParserConverter implements GenericConverter {} } public class GenericConversionService implements ConfigurableConversionService { private final Converters converters = new Converters(); public void addConverter(GenericConverter converter) { this.converters.add(converter); } }
Formatter最后還是被適配成GenericConverter(類型轉(zhuǎn)換接口)。
2、基于注解的格式化
字段格式化可以通過(guò)字段類型或注釋進(jìn)行配置。要將注釋綁定到Formatter,請(qǐng)實(shí)現(xiàn)AnnotationFormatterFactory。
public interface AnnotationFormatterFactory<A extends Annotation> { Set<Class<?>> getFieldTypes(); Printer<?> getPrinter(A annotation, Class<?> fieldType); Parser<?> getParser(A annotation, Class<?> fieldType); }
類及其方法說(shuō)明:
參數(shù)化A為字段注解類型,你希望將該字段與格式化邏輯關(guān)聯(lián),例如org.springframework.format.annotation.DateTimeFormat。
- getFieldTypes()返回可以使用注釋的字段類型。
- getPrinter()返回一個(gè)Printer來(lái)打印帶注釋的字段的值。
- getParser()返回一個(gè)Parser來(lái)解析帶注釋字段的clientValue。
自定義注解解析器。
public class StringToDateFormatter implements AnnotationFormatterFactory<DateFormatter> { @Override public Set<Class<?>> getFieldTypes() { return new HashSet<Class<?>>(Arrays.asList(Date.class)); } @Override public Printer<?> getPrinter(DateFormatter annotation, Class<?> fieldType) { return getFormatter(annotation, fieldType); } @Override public Parser<?> getParser(DateFormatter annotation, Class<?> fieldType) { return getFormatter(annotation, fieldType); } private StringFormatter getFormatter(DateFormatter annotation, Class<?> fieldType) { String pattern = annotation.value(); return new StringFormatter(pattern); } class StringFormatter implements Formatter<Date> { private String pattern; public StringFormatter(String pattern) { this.pattern = pattern; } @Override public String print(Date date, Locale locale) { return DateTimeFormatter.ofPattern(pattern, locale).format(date.toInstant()); } @Override public Date parse(String text, Locale locale) throws ParseException { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, locale); return Date.from(LocalDate.parse(text, formatter).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()); } } }
注冊(cè)及使用:
public class Main { @DateFormatter("yyyy年MM月dd日") private Date date; public static void main(String[] args) throws Exception { FormattingConversionService fcs = new FormattingConversionService(); fcs.addFormatterForFieldAnnotation(new StringToDateFormatter()); Main main = new Main(); Field field = main.getClass().getDeclaredField("date"); TypeDescriptor targetType = new TypeDescriptor(field); Object result = fcs.convert("2022年01月21日", targetType); System.out.println(result); field.setAccessible(true); field.set(main, result); System.out.println(main.date); } }
3、FormatterRegistry
FormatterRegistry是用于注冊(cè)格式化程序和轉(zhuǎn)換器的SPI。FormattingConversionService是FormatterRegistry的一個(gè)實(shí)現(xiàn),適用于大多數(shù)環(huán)境。可以通過(guò)編程或聲明的方式將該變體配置為Spring bean,例如使用FormattingConversionServiceFactoryBean。因?yàn)檫@個(gè)實(shí)現(xiàn)還實(shí)現(xiàn)了ConversionService,所以您可以直接配置它,以便與Spring的DataBinder和Spring表達(dá)式語(yǔ)言(SpEL)一起使用。
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); }
4、SpringMVC中配置類型轉(zhuǎn)換
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { // ... } }
SpringBoot中有如下的默認(rèn)類型轉(zhuǎn)換器。
public class WebMvcAutoConfiguration { public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware { @Bean @Override public FormattingConversionService mvcConversionService() { Format format = this.mvcProperties.getFormat(); WebConversionService conversionService = new WebConversionService(new DateTimeFormatters().dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime())); addFormatters(conversionService); return conversionService; } } }
到此這篇關(guān)于Spring中字段格式化的使用詳解的文章就介紹到這了,更多相關(guān)Spring字段格式化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java 漢諾塔Hanoi遞歸、非遞歸(仿系統(tǒng)遞歸)和非遞歸規(guī)律 實(shí)現(xiàn)代碼
漢諾塔(Hanoi) 算法Java實(shí)現(xiàn)。通過(guò)三個(gè)函數(shù),分別對(duì)Hanoi進(jìn)行遞歸、非遞歸和非遞歸規(guī)律實(shí)現(xiàn)。2013-05-05Spring data jpa的使用與詳解(復(fù)雜動(dòng)態(tài)查詢及分頁(yè),排序)
這篇文章主要介紹了Spring data jpa的使用與詳解(復(fù)雜動(dòng)態(tài)查詢及分頁(yè),排序),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11使用java代碼獲取新浪微博應(yīng)用的access token代碼實(shí)例
這篇文章主要介紹了使用java代碼獲取新浪微博應(yīng)用的access token實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05Maven實(shí)戰(zhàn)之搭建Maven私服和鏡像的方法(圖文)
本篇文章主要介紹了搭建Maven私服和鏡像的方法(圖文),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Spring?Boot集成RabbitMQ以及隊(duì)列模式操作
RabbitMQ是實(shí)現(xiàn)AMQP(高級(jí)消息隊(duì)列協(xié)議)的消息中間件的一種,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot集成RabbitMQ以及隊(duì)列模式操作的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04Eolink上傳文件到Java后臺(tái)進(jìn)行處理的示例代碼
這篇文章主要介紹了Eolink上傳文件到Java后臺(tái)進(jìn)行處理,這里是上傳的excel表格數(shù)據(jù)并轉(zhuǎn)換為java集合對(duì)象、然后進(jìn)行業(yè)務(wù)邏輯處理判斷最后保存到數(shù)據(jù)庫(kù)?,需要的朋友可以參考下2022-12-12