SpringMVC(八)數(shù)據(jù)轉(zhuǎn)換 & 數(shù)據(jù)格式化 & 數(shù)據(jù)校驗(yàn)

一到踏、數(shù)據(jù)綁定流程

1. Spring MVC 主框架將 ServletRequest 對(duì)象及目標(biāo)方法的入?yún)?shí)例傳遞給 WebDataBinderFactory 實(shí)例韭脊,以創(chuàng)建 DataBinder 實(shí)例對(duì)象

2. DataBinder 調(diào)用裝配在 Spring MVC 上下文中的ConversionService 組件進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換芥被、數(shù)據(jù)格式化工作诽里。將 Servlet 中的請(qǐng)求信息填充到入?yún)?duì)象中

3. 調(diào)用 Validator 組件對(duì)已經(jīng)綁定了請(qǐng)求消息的入?yún)?duì)象進(jìn)行數(shù)據(jù)合法性校驗(yàn)手负,并最終生成數(shù)據(jù)綁定結(jié)果BindingData 對(duì)象

4. Spring MVC 抽取 BindingResult 中的入?yún)?duì)象和校驗(yàn)錯(cuò)誤對(duì)象,將它們賦給處理方法的響應(yīng)入?yún)?/p>

5. Spring MVC 通過反射機(jī)制對(duì)目標(biāo)處理方法進(jìn)行解析茬祷,將請(qǐng)求消息綁定到處理方法的入?yún)⒅星寤馈?shù)據(jù)綁定的核心部件是DataBinder,運(yùn)行機(jī)制如下

二祭犯、數(shù)據(jù)轉(zhuǎn)換

Spring MVC 上下文中內(nèi)建了很多轉(zhuǎn)換器秸妥,可完成大多數(shù) Java 類型的轉(zhuǎn)換工作。

三沃粗、自定義類型轉(zhuǎn)換器

(1)ConversionService 是 Spring 類型轉(zhuǎn)換體系的核心接口粥惧。

(2)可以利用 ConversionServiceFactoryBean 在 Spring 的 IOC容器中定義一個(gè)ConversionService. Spring 將自動(dòng)識(shí)別出IOC 容器中的 ConversionService,并在 Bean 屬性配置及Spring MVC 處理方法入?yún)⒔壎ǖ葓龊鲜褂盟M(jìn)行數(shù)據(jù)的轉(zhuǎn)換最盅。

(3)可通過 ConversionServiceFactoryBean 的 converters 屬性 注冊(cè)自定義的類型轉(zhuǎn)換器突雪。?

四、Spring 支持的轉(zhuǎn)換器

Spring 定義了 3 種類型的轉(zhuǎn)換器接口檩禾,實(shí)現(xiàn)任意一個(gè)轉(zhuǎn)換器接口都可以作為自定義轉(zhuǎn)換器注冊(cè)到ConversionServiceFactroyBean 中:

(1)Converter<S,T>:將 S 類型對(duì)象轉(zhuǎn)為 T 類型對(duì)象

(2)ConverterFactory:將相同系列多個(gè) “同質(zhì)” Converter 封裝在一 起挂签。如果希望將一種類型的對(duì)象轉(zhuǎn)換為另一種類型及其子類的對(duì) 象(例如將 String 轉(zhuǎn)換為 Number 及 Number 子類(Integer、Long盼产、Double 等)對(duì)象)可使用該轉(zhuǎn)換器工廠類

(3)GenericConverter:會(huì)根據(jù)源類對(duì)象及目標(biāo)類對(duì)象所在的宿主類中的上下文信息進(jìn)行類型轉(zhuǎn)換

五、自定義轉(zhuǎn)換器示例

(1)input.jsp

(2)控制層

(3)自定義的轉(zhuǎn)換器

(4)配置

(5)輸入

(6)添加成功

六勺馆、關(guān)于 mvc:annotation-driven

<mvc:annotation-driven />會(huì)自動(dòng)注冊(cè)RequestMappingHandlerMapping戏售、RequestMappingHandlerAdapter 與ExceptionHandlerExceptionResolver 三個(gè)bean侨核。

還將提供以下支持:

(1)支持使用 ConversionService 實(shí)例對(duì)表單參數(shù)進(jìn)行類型轉(zhuǎn)換

(2)支持使用 @NumberFormat annotation、@DateTimeFormat注解完成數(shù)據(jù)類型的格式化

(3)支持使用 @Valid 注解對(duì) JavaBean 實(shí)例進(jìn)行 JSR 303 驗(yàn)證

(4)支持使用 @RequestBody 和 @ResponseBody 注解

既沒有配置<mvc:default-servlet-handler/>也沒有配置<mvc:annotation-driven/>

配置了<mvc:default-servlet-handler/>但沒有配置<mvc:annotation-driven/>

既配置了<mvc:default-servlet-handler/>又配置<mvc:annotation-driven/>

七灌灾、@InitBinder

由 @InitBinder 標(biāo)識(shí)的方法搓译,可以對(duì) WebDataBinder 對(duì) 象進(jìn)行初始化。WebDataBinder 是 DataBinder 的子類锋喜,用 于完成由表單字段到 JavaBean 屬性的綁定

@InitBinder方法不能有返回值些己,它必須聲明為void。

@InitBinder方法的參數(shù)通常是是 WebDataBinder

八嘿般、數(shù)據(jù)格式化

對(duì)屬性對(duì)象的輸入/輸出進(jìn)行格式化段标,從其本質(zhì)上講依然 屬于 “類型轉(zhuǎn)換” 的范疇。

Spring 在格式化模塊中定義了一個(gè)實(shí)現(xiàn)ConversionService 接口的FormattingConversionService 實(shí)現(xiàn)類炉奴,該實(shí)現(xiàn)類擴(kuò)展 了 GenericConversionService逼庞,因此它既具有類型轉(zhuǎn)換的 功能,又具有格式化的功能

FormattingConversionService 擁有一個(gè) FormattingConversionServiceFactroyBean 工廠類瞻赶,? 后者用于在 Spring 上下文中構(gòu)造前者

FormattingConversionServiceFactroyBean 內(nèi)部已經(jīng)注冊(cè)了 :

(1)NumberFormatAnnotationFormatterFactroy:支持對(duì)數(shù)字類型的屬性 使用 @NumberFormat 注解

(2)JodaDateTimeFormatAnnotationFormatterFactroy:支持對(duì)日期類型 的屬性使用 @DateTimeFormat 注解

裝配了 FormattingConversionServiceFactroyBean 后赛糟,就可以在 Spring MVC 入?yún)⒔壎澳P蛿?shù)據(jù)輸出時(shí)使用注解驅(qū)動(dòng) 了。

<mvc:annotation-driven/>默認(rèn)創(chuàng)建的ConversionService 實(shí)例即為FormattingConversionServiceFactroyBean

日期格式化

@DateTimeFormat 注解可對(duì)java.util.Date砸逊、java.util.Calendar璧南、java.long.Long 時(shí)間 類型進(jìn)行標(biāo)注:

pattern 屬性:類型為字符串。指定解析/格式化字段數(shù)據(jù)的模式师逸, 如:”yyyy-MM-dd hh:mm:ss”

iso 屬性:類型為 DateTimeFormat.ISO穆咐。指定解析/格式化字段數(shù)據(jù) 的ISO模式,包括四種:ISO.NONE(不使用) -- 默認(rèn)字旭、ISO.DATE(yyyy-MM-dd) 对湃、ISO.TIME(hh:mm:ss.SSSZ)、ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ)

style 屬性:字符串類型遗淳。通過樣式指定日期時(shí)間的格式拍柒,由兩位字符組成,第一位表示日期的格式屈暗,第二位表示時(shí)間的格式:S:短日 期/時(shí)間格式拆讯、M:中日期/時(shí)間格式、L:長日期/時(shí)間格式养叛、F:完整日期/時(shí)間格式种呐、-:忽略日期或時(shí)間格式

數(shù)值格式化

@NumberFormat 可對(duì)類似數(shù)字類型的屬性進(jìn)行標(biāo) 注,它擁有兩個(gè)互斥的屬性:

style:類型為 NumberFormat.Style弃甥。用于指定樣式類型爽室,包括三種:Style.NUMBER(正常數(shù)字類型)、Style.CURRENCY(貨幣類型)淆攻、 Style.PERCENT(? 百分?jǐn)?shù)類型)

pattern:類型為 String阔墩,自定義樣式嘿架, 如patter="#,###";

配置了這個(gè)還是沒有影響

轉(zhuǎn)換失敗

九啸箫、數(shù)據(jù)校驗(yàn)

JSR 303

JSR 303 是 Java 為 Bean 數(shù)據(jù)合法性校驗(yàn)提供的標(biāo)準(zhǔn)框架耸彪, 它已經(jīng)包含在 JavaEE 6.0 中 .

JSR 303 通過在 Bean 屬性上標(biāo)注類似于 @NotNull、@Max? 等標(biāo)準(zhǔn)的注解指定校驗(yàn)規(guī)則忘苛,并通過標(biāo)準(zhǔn)的驗(yàn)證接口對(duì) Bean? 進(jìn)行驗(yàn)證


Hibernate Validator 擴(kuò)展注解

Hibernate Validator 是 JSR 303 的一個(gè)參考實(shí)現(xiàn)蝉娜,除支持 所有標(biāo)準(zhǔn)的校驗(yàn)注解外,它還支持以下的擴(kuò)展注解

Spring MVC 數(shù)據(jù)校驗(yàn)

Spring 4.0 擁有自己獨(dú)立的數(shù)據(jù)校驗(yàn)框架扎唾,同時(shí)支持 JSR303 標(biāo)準(zhǔn)的校驗(yàn)框架召川。

Spring 在進(jìn)行數(shù)據(jù)綁定時(shí),可同時(shí)調(diào)用校驗(yàn)框架完成數(shù)據(jù)校驗(yàn)工作稽屏。在 Spring MVC 中扮宠,可直接通過注解驅(qū)動(dòng)的方式 進(jìn)行數(shù)據(jù)校驗(yàn)

Spring 的 LocalValidatorFactroyBean 既實(shí)現(xiàn)了 Spring 的Validator 接口,也實(shí)現(xiàn)了 JSR 303 的 Validator 接口狐榔。只要 在 Spring 容器中定義了一個(gè)LocalValidatorFactoryBean坛增,即可將其注入到需要數(shù)據(jù)校驗(yàn)的 Bean 中。

Spring 本身并沒有提供 JSR303 的實(shí)現(xiàn)薄腻,所以必須將JSR303 的實(shí)現(xiàn)者的 jar 包放到類路徑下收捣。

<mvc:annotation-driven/>會(huì)默認(rèn)裝配好一個(gè)LocalValidatorFactoryBean,通過在處理方法的入?yún)⑸蠘?biāo)注 @valid 注解即可讓 Spring MVC 在完成數(shù)據(jù)綁定后執(zhí)行 數(shù)據(jù)校驗(yàn)的工作

在已經(jīng)標(biāo)注了 JSR303 注解的表單/命令對(duì)象前標(biāo)注一個(gè) @Valid庵楷,Spring MVC 框架在將請(qǐng)求參數(shù)綁定到該入?yún)?duì)象 后罢艾,就會(huì)調(diào)用校驗(yàn)框架根據(jù)注解聲明的校驗(yàn)規(guī)則實(shí)施校驗(yàn)

Spring MVC 是通過對(duì)處理方法簽名的規(guī)約來保存校驗(yàn)結(jié)果 的:前一個(gè)表單/命令對(duì)象的校驗(yàn)結(jié)果保存到隨后的入?yún)⒅校@個(gè)保存校驗(yàn)結(jié)果的入?yún)⒈仨毷?BindingResult 或Errors 類型尽纽,這兩個(gè)類都位于org.springframework.validation 包中

需校驗(yàn)的 Bean 對(duì)象和其綁定結(jié)果對(duì)象或錯(cuò)誤對(duì)象時(shí)成對(duì)出現(xiàn)的咐蚯,它們之間不允許聲明其他的入?yún)?/p>

Errors 接口提供了獲取錯(cuò)誤信息的方法,如 getErrorCount() 或getFieldErrors(String field)

BindingResult 擴(kuò)展了 Errors 接口

在目標(biāo)方法中獲取校驗(yàn)結(jié)果

在表單/命令對(duì)象類的屬性中標(biāo)注校驗(yàn)注解弄贿,在處理方法對(duì) 應(yīng)的入?yún)⑶疤砑?@Valid春锋,Spring MVC 就會(huì)實(shí)施校驗(yàn)并將校 驗(yàn)結(jié)果保存在被校驗(yàn)入?yún)?duì)象之后的 BindingResult 或Errors 入?yún)⒅小?/p>

常用方法:

FieldError getFieldError(String field)

List<FieldError> getFieldErrors()

Object getFieldValue(String field)

Int getErrorCount()

測(cè)試

(1)先導(dǎo)入相關(guān)的包

(2)給實(shí)體的屬性上添加校驗(yàn)的注解

(3)在控制層的入?yún)⑶凹由螥Valid,還有出錯(cuò)就轉(zhuǎn)向定制頁面

(4)驗(yàn)證結(jié)果

在頁面上顯示錯(cuò)誤

Spring MVC 除了會(huì)將表單/命令對(duì)象的校驗(yàn)結(jié)果保存到對(duì) 應(yīng)的 BindingResult 或 Errors 對(duì)象中外差凹,還會(huì)將所有校驗(yàn) 結(jié)果保存到 “隱含模型”

即使處理方法的簽名中沒有對(duì)應(yīng)于表單/命令對(duì)象的結(jié)果 入?yún)⑵诒迹r?yàn)結(jié)果也會(huì)保存在 “隱含對(duì)象” 中。

隱含模型中的所有數(shù)據(jù)最終將通過 HttpServletRequest 的 屬性列表暴露給 JSP 視圖對(duì)象危尿,因此在 JSP 中可以獲取 錯(cuò)誤信息

在 JSP 頁面上可通過<form:errors path=“userName”>顯示錯(cuò)誤消息

提示消息的國際化

每個(gè)屬性在數(shù)據(jù)綁定和數(shù)據(jù)校驗(yàn)發(fā)生錯(cuò)誤時(shí)呐萌,都會(huì)生成一 個(gè)對(duì)應(yīng)的 FieldError 對(duì)象。

當(dāng)一個(gè)屬性校驗(yàn)失敗后谊娇,校驗(yàn)框架會(huì)為該屬性生成 4 個(gè)消 息代碼肺孤,這些代碼以校驗(yàn)注解類名為前綴,結(jié)合modleAttribute、屬性名及屬性類型名生成多個(gè)對(duì)應(yīng)的消息代碼:例如 User 類中的 password 屬性標(biāo)準(zhǔn)了一個(gè) @Pattern 注 解渠旁,當(dāng)該屬性值不滿足 @Pattern 所定義的規(guī)則時(shí), 就會(huì)產(chǎn)生以下 4? 個(gè)錯(cuò)誤代碼:

Pattern.user.password

Pattern.password

Pattern.java.lang.String

Pattern

當(dāng)使用 Spring MVC 標(biāo)簽顯示錯(cuò)誤消息時(shí)攀例, Spring MVC 會(huì)查看WEB 上下文是否裝配了對(duì)應(yīng)的國際化消息船逮,如果沒有顾腊,則顯示默認(rèn) 的錯(cuò)誤消息,否則使用國際化消息挖胃。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末杂靶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子酱鸭,更是在濱河造成了極大的恐慌吗垮,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凹髓,死亡現(xiàn)場離奇詭異烁登,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蔚舀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門饵沧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赌躺,你說我怎么就攤上這事狼牺。” “怎么了礼患?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵是钥,是天一觀的道長。 經(jīng)常有香客問我缅叠,道長悄泥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任肤粱,我火速辦了婚禮弹囚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘狼犯。我一直安慰自己余寥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布悯森。 她就那樣靜靜地躺著宋舷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓢姻。 梳的紋絲不亂的頭發(fā)上祝蝠,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼绎狭。 笑死细溅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的儡嘶。 我是一名探鬼主播喇聊,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼蹦狂!你這毒婦竟也來了誓篱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤凯楔,失蹤者是張志新(化名)和其女友劉穎窜骄,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摆屯,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡邻遏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了虐骑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片准验。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖富弦,靈堂內(nèi)的尸體忽然破棺而出沟娱,到底是詐尸還是另有隱情,我是刑警寧澤腕柜,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布济似,位于F島的核電站,受9級(jí)特大地震影響盏缤,放射性物質(zhì)發(fā)生泄漏砰蠢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一唉铜、第九天 我趴在偏房一處隱蔽的房頂上張望台舱。 院中可真熱鬧,春花似錦潭流、人聲如沸竞惋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拆宛。三九已至,卻和暖如春讼撒,著一層夾襖步出監(jiān)牢的瞬間浑厚,已是汗流浹背股耽。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钳幅,地道東北人物蝙。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像敢艰,于是被迫代替她去往敵國和親诬乞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架盖矫,建立于...
    Hsinwong閱讀 22,430評(píng)論 1 92
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理丽惭,服務(wù)發(fā)現(xiàn)击奶,斷路器辈双,智...
    卡卡羅2017閱讀 134,693評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,838評(píng)論 6 342
  • 前兩天讀到一首詞: 雁書蝶夢(mèng)皆成杳痰驱,月戶云窗人悄悄证芭。記得畫樓東,歸驄系月中担映。醒來燈未滅废士,心事和誰說。只有舊羅裳蝇完,偷...
    苦澀瑪奇朵閱讀 1,118評(píng)論 1 2
  • 遇見朱熹 入夜官硝,微風(fēng)輕揚(yáng),書上的你眼神神采飛揚(yáng)短蜕,牽引我穿過萬里時(shí)空氢架。 1169年,那時(shí)你意氣風(fēng)發(fā)朋魔,是思想界的一位大...
    含笑please閱讀 714評(píng)論 0 2