流程:java
一、首先建立數據綁定器,在此此會建立ServletRequestDataBinder類的對象,並設置messageCodesResolver(錯誤碼解析器);web
二、提供第一個擴展點,初始化數據綁定器,在此處咱們能夠覆蓋該方法註冊自定義的PropertyEditor(請求參數——>命令對象屬性的轉換);正則表達式
三、進行數據綁定,即請求參數——>命令對象的綁定;spring
四、提供第二個擴展點,數據綁定完成後的擴展點,此處能夠實現一些自定義的綁定動做;數組
五、驗證器對象的驗證,驗證器經過validators注入,若是驗證失敗,須要把錯誤信息放入Errors(此處使用BindException實現);瀏覽器
六、提供第三個擴展點,此處能夠實現自定義的綁定/驗證邏輯;架構
七、將errors傳入功能處理方法進行處理,功能方法應該判斷該錯誤對象是否有錯誤進行相應的處理。mvc
請求參數(String)——>命令對象屬性(多是任意類型)的類型轉換,即數據綁定時的類型轉換,使用PropertyEditor實現綁定時的類型轉換。jsp
1、Spring內建的PropertyEditor以下所示:編輯器
類名 |
說明 |
默認是否註冊 |
ByteArrayPropertyEditor |
String<——>byte[] |
√ |
ClassEditor |
String<——>Class 當類沒有發現拋出 |
√ |
CustomBooleanEditor |
String<——>Boolean true/yes/on/1轉換爲true,false/no/off/0轉換爲false |
√ |
CustomCollectionEditor |
數組/Collection——>Collection 普通值——>Collection(只包含一個對象) 如String——>Collection 不容許Collection——>String(單方向轉換) |
√ |
CustomNumberEditor |
String<——>Number(Integer、Long、Double) |
√ |
FileEditor |
String<——>File |
√ |
InputStreamEditor |
String——>InputStream 單向的,不能InputStream——>String |
√ |
LocaleEditor |
String<——>Locale, (String的形式爲[語言]_[國家]_[變量],這與Local對象的toString()方法獲得的結果相同) |
√ |
PatternEditor |
String<——>Pattern |
√ |
PropertiesEditor |
String<——>java.lang.Properties |
√ |
URLEditor |
String<——>URL |
√ |
StringTrimmerEditor |
一個用於trim 的 String類型的屬性編輯器 如默認刪除兩邊的空格,charsToDelete屬性:能夠設置爲其餘字符 emptyAsNull屬性:將一個空字符串轉化爲null值的選項。 |
× |
CustomDateEditor |
String<——>java.util.Date |
× |
2、Spring內建的PropertyEditor支持的屬性(符合JavaBean規範)操做:
表達式 |
設值/取值說明 |
username |
屬性username 設值方法setUsername()/取值方法getUsername() 或 isUsername() |
schooInfo.schoolType |
屬性schooInfo的嵌套屬性schoolType 設值方法getSchooInfo().setSchoolType()/取值方法getSchooInfo().getSchoolType() |
hobbyList[0] |
屬性hobbyList的第一個元素 索引屬性多是一個數組、列表、其它自然有序的容器。 |
map[key] |
屬性map(java.util.Map類型) map中key對應的值 |
3、示例:
接下來咱們寫自定義的屬性編輯器進行數據綁定:
(一、模型對象:
(二、PhoneNumber屬性編輯器
前臺輸入如010-12345678自動轉換爲PhoneNumberModel。
PropertyEditorSupport:一個PropertyEditor的支持類;
setAsText:表示將String——>PhoneNumberModel,根據正則表達式進行轉換,若是轉換失敗拋出異常,則接下來的驗證器會進行驗證處理;
getAsText:表示將PhoneNumberModel——>String。
(三、控制器
須要在控制器註冊咱們自定義的屬性編輯器。
此處咱們使用AbstractCommandController,由於它繼承了BaseCommandController,擁有綁定流程。
initBinder:第一個擴展點,初始化數據綁定器,在此處咱們註冊了兩個屬性編輯器;
CustomDateEditor:自定義的日期編輯器,用於在String<——>日期之間轉換;
binder.registerCustomEditor(Date.class, dateEditor):表示若是命令對象是Date類型,則使用dateEditor進行類型轉換;
PhoneNumberEditor:自定義的電話號碼屬性編輯器用於在String<——> PhoneNumberModel之間轉換;
binder.registerCustomEditor(PhoneNumberModel.class, newPhoneNumberEditor()):表示若是命令對象是PhoneNumberModel類型,則使用PhoneNumberEditor進行類型轉換;
(四、spring配置文件chapter4-servlet.xml
(五、視圖頁面(WEB-INF/jsp/bindAndValidate/success.jsp)
視圖頁面的數據沒有預期被格式化,如何進行格式化顯示呢?請參考【第七章 註解式控制器的數據驗證、類型轉換及格式化】。
(六、測試:
一、在瀏覽器地址欄輸入請求的URL,如
http://localhost:9080/springmvc-chapter4/dataBind?username=zhang&bool=yes&schooInfo.specialty=computer&hobbyList[0]=program&hobbyList[1]=music&map[key1]=value1&map[key2]=value2&phoneNumber=010-12345678&date=2012-3-18 16:48:48&state=blocked
二、控制器輸出的內容:
DataBinderTestModel [username=zhang, bool=true, schooInfo=SchoolInfoModel [schoolType=null, schoolName=null, specialty=computer], hobbyList=[program, music], map={key1=value1, key2=value2}, phoneNumber=PhoneNumberModel [areaCode=010, phoneNumber=12345678], date=Sun Mar 18 16:48:48 CST 2012, state=鎖定]
類型轉換如圖所示:
4、註冊PropertyEditor
一、使用WebDataBinder進行控制器級別註冊PropertyEditor(控制器獨享)
如「【3、示例】」中所使用的方式,使用WebDataBinder註冊控制器級別的PropertyEditor,這種方式註冊的PropertyEditor只對當前控制器獨享,即其餘的控制器不會自動註冊這個PropertyEditor,若是須要還須要再註冊一下。
二、使用WebBindingInitializer批量註冊
PropertyEditor
若是想在多個控制器同時註冊多個相同的PropertyEditor時,能夠考慮使用WebBindingInitializer。
示例:
(一、實現WebBindingInitializer
經過實現WebBindingInitializer並經過binder註冊多個PropertyEditor。
(二、修改【3、示例】中的DataBinderTestController,註釋掉initBinder方法;
(三、修改chapter4-servlet.xml配置文件:
(四、嘗試訪問「【3、示例】」中的測試URL便可成功。
使用WebBindingInitializer的好處是當你須要在多個控制器中須要同時使用多個相同的PropertyEditor能夠在WebBindingInitializer實現中註冊,這樣只須要在控制器中注入WebBindingInitializer便可注入多個PropertyEditor。
三、全局級別註冊PropertyEditor(全局共享)
只須要將咱們自定義的PropertyEditor放在和你的模型類同包下便可,且你的Editor命名規則必須是「模型類名Editor」,這樣Spring會自動使用標準JavaBean架構進行自動識別,如圖所示:
此時咱們把「DataBinderTestController」的「binder.registerCustomEditor(PhoneNumberModel.class, new PhoneNumberEditor());」註釋掉,再嘗試訪問「【3、示例】」中的測試URL便可成功。
這種方式不單單在使用Spring時可用,在標準的JavaBean等環境都是可用的,能夠認爲是全局共享的(不單單是Spring環境)。
PropertyEditor被限制爲只能String<——>Object之間轉換,不能Object<——>Object,Spring3提供了更強大的類型轉換(TypeConversion)支持,它能夠在任意對象之間進行類型轉換,不單單是String
<——>Object。
若是我在地址欄輸入錯誤的數據,即數據綁定失敗,Spring Web MVC該如何處理呢?若是我輸入的數據不合法呢?如用戶名輸入100個字符(超長了)那又該怎麼處理呢?出錯了須要錯誤消息,那錯誤消息應該是硬編碼?仍是可配置呢?
接下來咱們來學習一下數據驗證器進行數據驗證吧。