【SpringMVC學習06】SpringMVC中的資料校驗
這一篇博文主要總結一下springmvc中對資料的校驗。在實際中,通常使用較多是前端的校驗,比如頁面中js校驗,對於安全要求較高的建議在服務端也要進行校驗。服務端校驗可以是在控制層conroller,也可以是在業務層service,controller校驗頁面請求的引數的合法性,在服務端控制層conroller的校驗,不區分客戶端型別(瀏覽器、手機客戶端、遠端呼叫);service層主要校驗關鍵業務引數,僅限於service介面中使用的引數。這裡主要總結一下何如使用springmvc中controller的校驗。
1. 環境準備
springmvc中我們使用hibernate的校驗框架validation(注:和hibernate沒有任何關係),使用這個校驗框架的話,需要匯入jar包(
2. 配置校驗器
在springmvc.xml配置檔案中配置一下校驗器,如下:
<!-- 配置校驗器 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- 校驗器,使用hibernate校驗器 -->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!-- 指定校驗使用的資原始檔,在檔案中配置校驗錯誤資訊,如果不指定則預設使用classpath下面的ValidationMessages.properties檔案 -->
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<!-- 校驗錯誤資訊配置檔案 -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource" >
<!-- 資原始檔名 -->
<property name="basenames">
<list>
<value>classpath:CustomValidationMessage</value>
</list>
</property>
<!-- 資原始檔編碼格式 -->
<property name="fileEncodings" value="utf-8"/>
<!-- 對資原始檔內容快取時間,單位秒 -->
<property name="cacheSeconds" value="120"/>
</bean>
配置規則就是bean和property屬性,別把class和檔名寫錯了就行,這裡有個配置是資原始檔名,這個檔案中我們將會配置一些錯誤資訊。配置好了校驗器後,需要將校驗器注入到處理器介面卡中,還是在springmvc.xml檔案中,將我們配好的validator注入進去,如下:
這樣校驗器就配置好了。
3. 在pojo中新增校驗
hibernate校驗框架提供了很多註解校驗,我先簡單羅列一下:
註解 | 執行時檢查 |
---|---|
@AssertFalse | 被註解的元素必須為false |
@AssertTrue | 被註解的元素必須為true |
@DecimalMax(value) | 被註解的元素必須為一個數字,其值必須小於等於指定的最小值 |
@DecimalMin(Value) | 被註解的元素必須為一個數字,其值必須大於等於指定的最小值 |
@Digits(integer=, fraction=) | 被註解的元素必須為一個數字,其值必須在可接受的範圍內 |
@Future | 被註解的元素必須是日期,檢查給定的日期是否比現在晚 |
@Max(value) | 被註解的元素必須為一個數字,其值必須小於等於指定的最小值 |
@Min(value) | 被註解的元素必須為一個數字,其值必須大於等於指定的最小值 |
@NotNull | 被註解的元素必須不為null |
@Null | 被註解的元素必須為null |
@Past(java.util.Date/Calendar) | 被註解的元素必須過去的日期,檢查標註物件中的值表示的日期比當前早 |
@Pattern(regex=, flag=) | 被註解的元素必須符合正則表示式,檢查該字串是否能夠在match指定的情況下被regex定義的正則表示式匹配 |
@Size(min=, max=) | 被註解的元素必須在制定的範圍(資料型別:String, Collection, Map and arrays) |
@Valid | 遞迴的對關聯物件進行校驗, 如果關聯物件是個集合或者陣列, 那麼對其中的元素進行遞迴校驗,如果是一個map,則對其中的值部分進行校驗 |
@CreditCardNumber | 對信用卡號進行一個大致的驗證 |
被註釋的元素必須是電子郵箱地址 | |
@Length(min=, max=) | 被註解的物件必須是字串的大小必須在制定的範圍內 |
@NotBlank | 被註解的物件必須為字串,不能為空,檢查時會將空格忽略 |
@NotEmpty | 被註釋的物件必須為空(資料:String,Collection,Map,arrays) |
@Range(min=, max=) | 被註釋的元素必須在合適的範圍內 (資料:BigDecimal, BigInteger, String, byte, short, int, long and 原始型別的包裝類 ) |
@URL(protocol=, host=, port=, regexp=, flags=) | 被註解的物件必須是字串,檢查是否是一個有效的URL,如果提供了protocol,host等,則該URL還需滿足提供的條件 |
上面我簡單羅列了一些校驗的註解,不同的註解的具體使用方法可以參考官方文件或者網上資料,這裡我選擇兩個註解來說明如何使用這個hibernate驗證框架。首先在自己的pojo中需要驗證的屬性上新增相應的驗證註解:
我們看到註解中可以指定message,那麼這個message中的內容是錯誤訊息配置檔案中對應的key,取出來的就是對應的錯誤訊息,所以針對這兩個錯誤訊息,我們寫一下配置檔案:
4. 捕獲校驗錯誤資訊
上面已經將校驗相關的配置都配好了,接下來就需要在controller的方法中捕獲校驗結果中的錯誤資訊,然後將這些錯誤資訊傳到前臺去顯示。那麼controller的方法中該如何去捕獲呢?如下:
可以看出,在需要校驗的pojo前邊新增@Validated,在需要校驗的pojo後邊新增BindingResult bindingResult來接收校驗出錯資訊。值得注意的是:@Validated和BindingResult bindingResult是配對出現,並且形參順序是固定的(一前一後)。這樣就可以順利接收到錯誤資訊了。關於前臺的東西,我就不寫了。
5. 分組校驗
上面已經能完成springmvc的校驗功能了,但是有個問題:剛剛是在pojo中定義了校驗規則,但是pojo是被多個controller使用的,現在假如兩個不同的controller使用的校驗規則是不一樣的,簡單來說,一個controller不需要去校驗生產日期,只要校驗一下商品名稱即可,另一個controller兩個都要校驗,這樣就沒法做了,因為兩個controller都使用同一個pojo。
為了解決這個問題,我們可以定義多個校驗分組(其實是一個java介面),分組中定義有哪些規則,每個controller方法使用不同的校驗分組即可。看一下下面的例子就明白了:
首先定義一個校驗分組:
public interface ValidGroup1 {
//介面中不需要定義任何方法,僅僅是對不同的校驗規則進行分組
//此分組只校驗商品名稱的長度
}
然後我們在剛剛的pojo中,新增這個分組,如下:
再看一下想要校驗這個name欄位的controller中是如何配置的:
這樣該controller就不會去校驗生產日期的欄位了,通過這種方式可以解決不同的controller校驗不同欄位的問題。
文末福利:“程式設計師私房菜”,一個有溫度的公眾號~