首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring 類型轉換體系深度解析:Converter、ConversionService 與格式化最佳實踐

     編輯:Java 綜合教學

前言:為什麼需要類型轉換體系?

Web 開發中,HTTP 參數全是 String,但 Controller 方法參數卻是 Integer、Date、Enum、自定義對象等。Spring 的 ConversionService 體系將「字符串 → 目標類型」的轉換邏輯標準化、集中化、可擴展化,避免 Controller 充斥解析代碼。

核心接口架構

// 核心轉換器接口(S -> T)
public interface Converter<S, T> {
    T convert(S source);
}

// 統一服務入口
public interface ConversionService {
    boolean canConvert(Class<?> sourceType, Class<?> targetType);
    <T> T convert(Object source, Class<T> targetType);
    // ...
}

// 格式化接口(雙向:對象 ↔ 字符串,帶 Locale)
public interface Formatter<T> extends Printer<T>, Parser<T> {}

實戰:String → Date 自定義轉換器

1. 實現 Converter 接口

public class StringToDateConverter implements Converter<String, Date> {
    private String pattern = "yyyy-MM-dd"; // 默認格式

    public void setPattern(String pattern) { this.pattern = pattern; }

    @Override
    public Date convert(String source) {
        try {
            return new SimpleDateFormat(pattern).parse(source);
        } catch (ParseException e) {
            throw new ConversionFailedException(
                TypeDescriptor.valueOf(String.class),
                TypeDescriptor.valueOf(Date.class),
                source, e);
        }
    }
}

2. 註冊到 ConversionService

<bean id="conversionService" 
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.example.converter.StringToDateConverter">
                <property name="pattern" value="yyyy-MM-dd HH:mm:ss"/>
            </bean>
            <!-- 其他自定義轉換器 -->
        </set>
    </property>
</bean>

3. 在 Spring MVC 中啟用

<mvc:annotation-driven conversion-service="conversionService" />

現在 Controller 直接接收 Date 參數:

@GetMapping("/search")
public List<Order> search(@RequestParam("startDate") Date startDate) {
    // 自動轉換 "2024-01-15" → Date
    return orderService.findByDate(startDate);
}

進階:Formatter 實現雙向格式化(含 Locale)

public class DateFormatter implements Formatter<Date> {
    private String pattern = "yyyy-MM-dd";

    @Override // 對象 → 字符串(顯示)
    public String print(Date date, Locale locale) {
        return new SimpleDateFormat(pattern, locale).format(date);
    }

    @Override // 字符串 → 對象(解析)
    public Date parse(String text, Locale locale) throws ParseException {
        return new SimpleDateFormat(pattern, locale).parse(text);
    }
}

註冊:

<bean id="conversionService" class="...ConversionServiceFactoryBean">
    <property name="formatters">
        <set><bean class="com.example.format.DateFormatter"/></set>
    </property>
</bean>

Spring 內建轉換器概覽(常用即開箱即用)

轉換器來源 → 目標說明
StringToNumberConverterFactoryString → Number 子類Integer、Long、Double、BigDecimal 等
StringToBooleanConverterString → Boolean"true"/"false", "yes"/"no", "on"/"off"
StringToEnumConverterFactoryString → Enum按 name() 或 toString() 匹配
ObjectToObjectConverter任意 → 任意通過 toString/valueOf 兜底
Collection/Array/Map 轉換器String ↔ Collection逗號分隔字符串 ↔ List/Set

最佳實踐總結

  1. 優先使用內建:@DateTimeFormat、@NumberFormat 註解直接標註字段/參數
  2. 自定義 Converter:單向轉換(如 String → Entity)
  3. 自定義 Formatter:雙向格式化(如表單回顯、國際化)
  4. 註冊策略:全局 ConversionServiceFactoryBean + mvc:annotation-driven
  5. 異常處理:拋出 ConversionFailedException,配合 @ControllerAdvice 統一返回友好錯誤

總結

Spring 類型轉換體系將「解析邏輯」從業務代碼中剝離,形成可複用、可測試、可擴展的基礎設施。掌握 Converter(單向)、Formatter(雙向+Locale)、ConversionService(統一入口)三層架構,能讓 Controller 保持乾淨專注於業務流轉。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved