Spring 3 類型轉換與驗證

工程 | Keith Donald | 2009年11月17日 | ...

Spring 3 最終版本即將問世,這將會是一個很棒的版本。在這篇部落格文章中,我將帶您了解 Spring 3 的一些類型轉換和驗證增強功能。無論您正在開發傳統的 Web 應用程式、桌面應用程式,還是「下一代」RIA,資料綁定、類型轉換和驗證都是重要的領域。正如您將在這篇文章中看到的,Spring 3 在這些領域的每一個都為您提供了顯著的升級,同時保持了與先前版本的向後相容性。

新系統目標

在深入探討功能之前,我想先強調我們在著手改進 Spring 3 的資料綁定系統時的目標

  1. 提供一個無狀態、強型別的類型轉換器 SPI,以取代 JavaBean PropertyEditors
  2. 提供一個統一的類型轉換 API,用於任何需要轉換的地方,包括 Spring 的 DataBinder 和表達式語言
  3. 允許類型轉換由 Java 註解元數據驅動
  4. 透過註冊合理的預設值並應用慣例優於配置來簡化
隨著 Spring 3 最終版本的臨近,我相信我們已經實現了每一個目標。請繼續閱讀,您自己來判斷。

功能

第一個充分利用新類型轉換系統的環境是 Spring MVC,我將從中提取範例來示範新功能。這從新的 Spring MVC 3 配置命名空間開始


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <mvc:annotation-driven />

</beans>

上述最小配置會使 Spring 自動安裝預設的類型轉換器,這些轉換器會本地化 Number 和 Date 欄位,包括完全支援流行的 Joda Time 函式庫(如果它存在於您的類別路徑中)。此外,如果 JSR-303 提供者(例如 Hibernate Validator)存在於您的類別路徑中,Spring 會自動啟用註解驅動的宣告式驗證。

現在,當您綁定到欄位時,將會使用合理的預設格式,針對使用者的地區設定列印和解析該欄位。為了說明,請考慮以下模型


public class Account {

    private Date activationDate = new Date(1258466400);

    private BigDecimal balance = new BigDecimal("3000.25");
}

...針對美國和德國地區設定的使用者在表單上列印

Locale.US Locale.DE
啟用日期

餘額

啟用日期

餘額

使用註解覆寫預設值

通常,您需要以不同於預設格式的方式格式化欄位。在先前的範例中,您可能希望使用簡短日期格式格式化activationDate欄位,並使用貨幣格式格式化balance欄位。在先前版本的 Spring 中,您會在 Controller 中註冊自訂 PropertyEditor 來實現此目的。在 Spring 3 中,您只需註解您的欄位


private class Account {

    @DateTimeFormat(style="S-")
    private Date activationDate = new Date(1258466400);

    @NumberFormat(style=Style.CURRENCY)
    private BigDecimal balance = new BigDecimal("3000.25");
}

透過註解覆寫,以下是針對美國和德國地區設定列印的內容

Locale.US Locale.DE
啟用日期

餘額

啟用日期

餘額

參數註解

註解驅動的覆寫也可以應用於方法參數。考慮以下 Controller 方法,該方法提取特定日期的即將到來的預約,其中日期是以 ISO 日期格式編碼的 URL 路徑變數


    @RequestMapping(value = "/appointments/{day}", method = RequestMethod.GET)
    public String getAppointmentsForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day) {
        ...
    }

向 /appointments/2009-11-17 發送 GET 請求會提取 2009 年 11 月 17 日的所有預約。將 @DateTimeFormat iso 屬性設定為 ISO.DATE 會指示 Spring 將傳入的日期字串解析為 ISO 日期 (yyyy-mm-dd)。

驗證

在將使用者輸入綁定到模型後驗證模型是很常見的。Spring 3 提供對 JSR-303 宣告式驗證的支援。如果 JSR-303 提供者(例如 Hibernate Validator)存在於您的類別路徑中,則會自動啟用此支援。啟用後,您可以透過簡單地使用 @Valid 註解註解 Controller 方法參數來觸發驗證


    @RequestMapping(value = "/appointments", method = RequestMethod.POST)
    public String add(@Valid AppointmentForm form, BindingResult result) {
        ....
    }

    static class AppointmentForm {

        @NotNull @Future
        private Date date;
    }

在綁定傳入的 POST 參數後,將會驗證 AppointmentForm;在這種情況下,驗證 date 欄位值是否為非空值,並且是否在未來。

慣例優於配置

最後,考慮如何將慣例優於配置原則應用於類型轉換。在業務應用程式中,您通常會定義自己的自訂欄位類型。在先前版本的 Spring 中,為了格式化此類類型,您將建立自訂 PropertyEditor 實作並在您的 Controller 中註冊它。使用 Spring 3,在大多數情況下,您只需遵守以下慣例

  1. 定義靜態 valueOf(String) 方法或建構子(String) 以從其字串表示形式解析您的值
  2. 實作 toString() 以列印您的值以供顯示

考慮一個 SocialSecurityNumber 類型,它遵守此慣例


    public class SocialSecurityNumber {

        @Size(9)
        @Mask("###-##-####")
        private String value;

        public SocialSecurityNumber(String value) {
            this.value = value;
        }

        public String toString() {
            return this.value;
        }
    }

當列印 SocialSecurityNumber 欄位以供顯示時,將會呼叫 toString();當解析用戶端值時,將會呼叫建構子。不需要單獨的 Formatter 或 PropertyEditor 實作。

摘要

這篇文章涵蓋了 Spring 3 的一些新類型轉換和驗證功能。若要了解更多資訊,包括如何實作您自己的類型轉換器,請查看 Spring 3 參考指南。此外,請注意即將發布的修訂版 Petclinic 3 範例應用程式(此範例應用程式示範了此處強調的所有功能,目前可在我們的 SVN 儲存庫 此處 搶先體驗)。

我對這些新功能為我們前進提供的基礎感到興奮!請務必讓我了解您應用和擴展這些功能的經驗,並在 jira.springframework.org 持續提供回饋和想法。

取得 Spring 電子報

與 Spring 電子報保持聯繫

訂閱

搶先一步

VMware 提供訓練與認證,以加速您的進展。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將到來的活動

查看 Spring 社群中所有即將到來的活動。

檢視全部