最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring處理字段格式化的實(shí)戰(zhàn)指南

 更新時(shí)間:2025年10月27日 10:15:29   作者:lang20150928  
本文講解 Spring 如何在客戶(hù)端環(huán)境(如 Web 應(yīng)用)中處理 字段的格式化與解析,特別是字符串與對(duì)象之間的雙向轉(zhuǎn)換,并支持國(guó)際化(Locale),將從 整體架構(gòu)、核心概念、SPI 接口、使用方式和實(shí)際應(yīng)用 五個(gè)維度,幫你系統(tǒng)性地理解,需要的朋友可以參考下

一、整體架構(gòu):Spring 類(lèi)型轉(zhuǎn)換體系

Spring 提供了兩套互補(bǔ)的類(lèi)型轉(zhuǎn)換機(jī)制:

模塊用途特點(diǎn)
core.convert 包下的 Converter SPI通用類(lèi)型轉(zhuǎn)換(如 LongDate通用性強(qiáng),不涉及字符串格式化或 Locale
format 包下的 Formatter SPI客戶(hù)端字段格式化(如 StringDate,帶格式和語(yǔ)言)面向 UI 層,支持 Locale,適合 Web 應(yīng)用

它們都由一個(gè)統(tǒng)一的服務(wù)接口管理:
ConversionService —— 是 Spring 內(nèi)部進(jìn)行類(lèi)型轉(zhuǎn)換的核心接口。

關(guān)鍵點(diǎn)

  • Converter:用于任意類(lèi)型之間轉(zhuǎn)換(后臺(tái)邏輯用)。
  • Formatter:專(zhuān)門(mén)用于 String 和目標(biāo)類(lèi)型之間轉(zhuǎn)換(前端展示/提交用)。
  • 兩者都被 ConversionService 管理,可共存。

二、核心概念:Formatter SPI

1. Formatter<T> 接口

這是 Spring 為“客戶(hù)端字段格式化”設(shè)計(jì)的核心接口:

public interface Formatter<T> extends Printer<T>, Parser<T> {
}

它由兩個(gè)子接口組成:

(1) Printer<T>:對(duì)象 → 字符串(用于顯示)

String print(T fieldValue, Locale locale);
  • 把 Java 對(duì)象(如 Date)按指定語(yǔ)言環(huán)境(Locale)格式化成字符串,用于頁(yè)面展示。
  • 例如:new Date()"2025-04-05"

(2) Parser<T>:字符串 → 對(duì)象(用于解析請(qǐng)求)

T parse(String clientValue, Locale locale) throws ParseException;
  • 把用戶(hù)提交的字符串(如表單輸入)解析為 Java 對(duì)象。
  • 例如:"2025-04-05"java.util.Date

要求

  • 實(shí)現(xiàn)必須是 線(xiàn)程安全 的(因?yàn)闀?huì)被多個(gè)請(qǐng)求共享)。
  • 解析失敗應(yīng)拋出 ParseException 或 IllegalArgumentException。

2. 內(nèi)置 Formatter 實(shí)現(xiàn)(開(kāi)箱即用)

Spring 提供了一些常用的 Formatter 實(shí)現(xiàn):

Formatter作用
NumberStyleFormatter格式化數(shù)字(支持千分位、小數(shù)點(diǎn)等)
CurrencyStyleFormatter顯示貨幣(如 ¥1,234.00)
PercentStyleFormatter百分比顯示(如 50%)
DateFormatterSimpleDateFormat 格式化日期

示例:DateFormatter 實(shí)現(xiàn)了 print()parse(),使用 patternLocale 來(lái)格式化日期。

三、高級(jí)特性:注解驅(qū)動(dòng)的格式化(Annotation-driven Formatting)

為了更方便地配置格式化規(guī)則,Spring 支持通過(guò) 注解 + 工廠(chǎng)模式 來(lái)綁定格式化邏輯。

1. AnnotationFormatterFactory<A extends Annotation>

這個(gè)接口的作用是:將某個(gè)注解映射到具體的 PrinterParser

public interface AnnotationFormatterFactory<A extends Annotation> {
    Set<Class<?>> getFieldTypes();        // 支持哪些字段類(lèi)型?
    Printer<?> getPrinter(A annotation, Class<?> fieldType);
    Parser<?> getParser(A annotation, Class<?> fieldType);
}

示例:NumberFormatAnnotationFormatterFactory

它處理 @NumberFormat 注解:

@NumberFormat(style = Style.CURRENCY)
private BigDecimal price;
  • 當(dāng) Spring 遇到這個(gè)字段時(shí),會(huì)查找注冊(cè)的 AnnotationFormatterFactory
  • 找到后調(diào)用 getPrinter() / getParser() 獲取對(duì)應(yīng)的格式化工廠(chǎng)
  • 最終使用 CurrencyStyleFormatter 來(lái)格式化金額

2. 常見(jiàn)格式化注解(在 org.springframework.format.annotation 包下)

注解用途
@NumberFormat數(shù)字格式化(支持 pattern 或 style)
@DateTimeFormat日期時(shí)間格式化(支持 ISO 格式、自定義 pattern)

示例:

public class MyModel {
    @DateTimeFormat(iso = ISO.DATE)  // 格式:yyyy-MM-dd
    private Date birthDate;

    @NumberFormat(pattern = "#,###.00")
    private Double salary;
}

這樣就不需要在每個(gè) controller 里手動(dòng)寫(xiě) new SimpleDateFormat(...),而是統(tǒng)一管理。

四、注冊(cè)機(jī)制 SPI:如何讓 Spring 知道你的 Formatter?

Spring 提供了幾個(gè) SPI 接口來(lái)注冊(cè)格式化器。

1. FormatterRegistry(核心注冊(cè)中心)

它是 ConverterRegistry 的擴(kuò)展,允許你注冊(cè):

void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter);
void addFormatterForAnnotation(AnnotationFormatterFactory<?> factory);

所有 formatter/converter 都要注冊(cè)到這里才能生效。

2. FormattingConversionService(推薦實(shí)現(xiàn)類(lèi))

這是一個(gè)標(biāo)準(zhǔn)實(shí)現(xiàn),實(shí)現(xiàn)了 ConversionService + FormatterRegistry,適合大多數(shù)場(chǎng)景。

你可以:

  • 編程式注冊(cè)(Java Config)
  • 聲明式注冊(cè)(XML)

3. FormatterRegistrar(批量注冊(cè)工具)

有時(shí)候你需要一次性注冊(cè)多個(gè) formatter(比如所有日期相關(guān)的),但直接注冊(cè)不方便(比如類(lèi)型擦除問(wèn)題),這時(shí)可以用:

public interface FormatterRegistrar {
    void registerFormatters(FormatterRegistry registry);
}

常見(jiàn)用途:

  • 注冊(cè) Joda-Time 所有格式化器
  • 設(shè)置全局日期格式
  • 批量注冊(cè) JSR-310 (java.time) 類(lèi)型的 formatter

五、實(shí)戰(zhàn)應(yīng)用:如何配置全局日期格式?

默認(rèn)情況下,未標(biāo)注 @DateTimeFormatDate 字段會(huì)用 DateFormat.SHORT(如 4/5/25)格式化,這通常不符合中國(guó)習(xí)慣。

目標(biāo):設(shè)置全局日期格式為 yyyyMMdd

方法一:Java 配置(推薦)

@Configuration
public class AppConfig {

    @Bean
    public FormattingConversionService conversionService() {
        // 創(chuàng)建 ConversionService,但不注冊(cè)默認(rèn) formatter
        DefaultFormattingConversionService service = new DefaultFormattingConversionService(false);

        // 保留 @NumberFormat 支持
        service.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());

        // 設(shè)置全局日期格式:yyyyMMdd
        DateFormatterRegistrar registrar = new DateFormatterRegistrar();
        registrar.setFormatter(new DateFormatter("yyyyMMdd"));
        registrar.registerFormatters(service);

        return service;
    }
}

方法二:XML 配置(傳統(tǒng)項(xiàng)目)

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="registerDefaultFormatters" value="false"/>
    <property name="formatters">
        <set>
            <bean class="org.springframework.format.number.NumberFormatAnnotationFormatterFactory"/>
        </set>
    </property>
    <property name="formatterRegistrars">
        <set>
            <bean class="org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar">
                <property name="dateFormatter">
                    <bean class="org.springframework.format.datetime.joda.DateTimeFormatterFactoryBean">
                        <property name="pattern" value="yyyyMMdd"/>
                    </bean>
                </property>
            </bean>
        </set>
    </property>
</bean>

六、總結(jié):一句話(huà)理解全文

Spring 的 Formatter SPI 是為 客戶(hù)端環(huán)境(如 Web 頁(yè)面)設(shè)計(jì)的一套 基于 Locale 的字符串 ↔ 對(duì)象 轉(zhuǎn)換機(jī)制,相比通用的 Converter,它更適合處理用戶(hù)輸入和輸出的格式化需求,且支持注解驅(qū)動(dòng)(如 @DateTimeFormat)、可集中配置、易于擴(kuò)展。

七、常見(jiàn)問(wèn)題解答(FAQ)

Q1: Formatter 和 PropertyEditor 有什么區(qū)別?

  • PropertyEditor 是 JavaBeans 規(guī)范的老技術(shù),線(xiàn)程不安全,API 不夠靈活。
  • Formatter 是 Spring 3 新引入的,線(xiàn)程安全、強(qiáng)類(lèi)型、支持 Locale,推薦替代 PropertyEditor。

Q2: 在 Spring MVC 中怎么啟用這些 formatter?

只要把自定義的 FormattingConversionService 注入到 Spring MVC 的配置中即可:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new DateFormatter("yyyyMMdd"));
    }
}

或者使用 <mvc:annotation-driven conversion-service="conversionService"/> XML 配置。

Q3: JSR-310 時(shí)間類(lèi)(LocalDate、LocalDateTime)支持嗎?

支持!Spring 會(huì)自動(dòng)注冊(cè) java.time 類(lèi)型的 formatter。你可以通過(guò) DateTimeFormatterRegistrar 控制其格式。

如果你正在開(kāi)發(fā) Web 應(yīng)用,尤其是需要處理表單提交、日期顯示、貨幣格式等功能,那么這一套 Formatter 機(jī)制就是你應(yīng)該掌握的核心技能之一。

需要我根據(jù)你的具體場(chǎng)景(比如 Spring Boot 項(xiàng)目)給出一個(gè)完整的配置示例嗎?

以上就是Spring處理字段格式化的實(shí)戰(zhàn)指南的詳細(xì)內(nèi)容,更多關(guān)于Spring處理字段格式化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java?Spring?AOP源碼解析之事務(wù)實(shí)現(xiàn)原理

    Java?Spring?AOP源碼解析之事務(wù)實(shí)現(xiàn)原理

    這篇文章主要為大家介紹了Java?Spring?AOP事務(wù)實(shí)現(xiàn)原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • MyBatis在Mapper中傳遞多個(gè)參數(shù)的四種方法詳解

    MyBatis在Mapper中傳遞多個(gè)參數(shù)的四種方法詳解

    這篇文章主要介紹了MyBatis在Mapper中傳遞多個(gè)參數(shù)的四種方法,文章通過(guò)代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,,需要的朋友可以參考下
    2023-09-09
  • 使用Java和WebSocket實(shí)現(xiàn)網(wǎng)頁(yè)聊天室實(shí)例代碼

    使用Java和WebSocket實(shí)現(xiàn)網(wǎng)頁(yè)聊天室實(shí)例代碼

    WebSocket是HTML5一種新的協(xié)議,它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信,這里就將使用WebSocket來(lái)開(kāi)發(fā)網(wǎng)頁(yè)聊天室,對(duì)Java和WebSocket實(shí)現(xiàn)網(wǎng)頁(yè)聊天室的實(shí)例代碼感興趣的朋友一起學(xué)習(xí)吧
    2016-06-06
  • java讀取枚舉類(lèi)的值轉(zhuǎn)成list和map方式

    java讀取枚舉類(lèi)的值轉(zhuǎn)成list和map方式

    這篇文章主要介紹了java讀取枚舉類(lèi)的值轉(zhuǎn)成list和map方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring Validation數(shù)據(jù)校驗(yàn)詳解

    Spring Validation數(shù)據(jù)校驗(yàn)詳解

    SpringValidation是Spring框架的數(shù)據(jù)校驗(yàn)抽象層,支持注解、分組、嵌套校驗(yàn)及國(guó)際化,默認(rèn)集成HibernateValidator,可自定義校驗(yàn)器滿(mǎn)足復(fù)雜需求,適用于Web參數(shù)校驗(yàn)和業(yè)務(wù)邏輯驗(yàn)證
    2025-09-09
  • JAVA socket.io注解原理及用法圖解

    JAVA socket.io注解原理及用法圖解

    這篇文章主要介紹了JAVA socket.io注解原理及用法圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Java連接ftp服務(wù)器實(shí)例代碼

    Java連接ftp服務(wù)器實(shí)例代碼

    這篇文章主要介紹了Java連接ftp服務(wù)器實(shí)例代碼 的相關(guān)資料,需要的朋友可以參考下
    2015-12-12
  • 淺談SpringBoot中的@Conditional注解的使用

    淺談SpringBoot中的@Conditional注解的使用

    這篇文章主要介紹了淺談SpringBoot中的@Conditional注解的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • java.sql.SQLException問(wèn)題解決以及注意事項(xiàng)

    java.sql.SQLException問(wèn)題解決以及注意事項(xiàng)

    這篇文章主要給大家介紹了關(guān)于java.sql.SQLException問(wèn)題解決以及注意事項(xiàng)的相關(guān)資料,這個(gè)問(wèn)題其實(shí)很好解決,文中通過(guò)圖文將解決的辦法介紹的很詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之食品溯源系統(tǒng)的實(shí)現(xiàn)

    Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之食品溯源系統(tǒng)的實(shí)現(xiàn)

    這是一個(gè)使用了java+Springboot+Maven+mybatis+Vue+mysql+wd開(kāi)發(fā)的食品溯源系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有食品溯源該有的所有功能,感興趣的朋友快來(lái)看看吧
    2022-01-01

最新評(píng)論

海宁市| 张家口市| 肥城市| 荆门市| 台中市| 东乌珠穆沁旗| 行唐县| 项城市| 民乐县| 明溪县| 伽师县| 古交市| 天台县| 德安县| 绥宁县| 大安市| 沐川县| 明水县| 洛隆县| 曲松县| 南丰县| 辰溪县| 洞口县| 丰台区| 庐江县| 白水县| 湟源县| 五指山市| 日喀则市| 九龙县| 麻城市| 珲春市| 股票| 太保市| 高陵县| 海南省| 丘北县| 邵东县| 上犹县| 彩票| 鹤庆县|