詳解SpringMVC驗(yàn)證框架Validation特殊用法
基本用法不說(shuō)了,網(wǎng)上例子很多,這里主要介紹下比較特殊情況下使用的方法。
1. 分組
有的時(shí)候,我們對(duì)一個(gè)實(shí)體類(lèi)需要有多中驗(yàn)證方式,在不同的情況下使用不同驗(yàn)證方式,比如說(shuō)對(duì)于一個(gè)實(shí)體類(lèi)來(lái)的id來(lái)說(shuō),保存的時(shí)候是不需要的,對(duì)于更新時(shí)是必須的,可以如下配置:
public class UserModel {
@NotNull(message = "{id.empty}", groups = { First.class })
private int id;
@NotNull(message = "{username.empty}", groups = { First.class, Second.class })
private String username;
@NotNull(message = "{content.empty}", groups = { First.class, Second.class })
private String content;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
public interface First {
}
public interface Second {
}
通過(guò) groups 對(duì)驗(yàn)證進(jìn)行分組
在controler中的代碼如下:
@RequestMapping(value = "/save.action", method = RequestMethod.POST)
public String save(@Validated( { Second.class }) UserModel userModel, BindingResult result) {
if (result.hasErrors()) {
return "validate/error";
}
return "redirect:/success";
}
@RequestMapping(value = "/update.action", method = RequestMethod.POST)
public String update(@Validated( { First.class, Second.class }) UserModel user, BindingResult result) {
if (result.hasErrors()) {
return "validate/error";
}
return "redirect:/success";
}
2. 組序列
默認(rèn)情況下,不同組別的約束驗(yàn)證是無(wú)序的,然而在某些情況下,約束驗(yàn)證的順序卻很重要,如下面兩個(gè)例子:(1)第二個(gè)組中的約束驗(yàn)證依賴(lài)于一個(gè)穩(wěn)定狀態(tài)來(lái)運(yùn)行,而這個(gè)穩(wěn)定狀態(tài)是由第一個(gè)組來(lái)進(jìn)行驗(yàn)證的。(2)某個(gè)組的驗(yàn)證比較耗時(shí),CPU 和內(nèi)存的使用率相對(duì)比較大,最優(yōu)的選擇是將其放在最后進(jìn)行驗(yàn)證。因此,在進(jìn)行組驗(yàn)證的時(shí)候尚需提供一種有序的驗(yàn)證方式,這就提出了組序列的概念。
一個(gè)組可以定義為其他組的序列,使用它進(jìn)行驗(yàn)證的時(shí)候必須符合該序列規(guī)定的順序。在使用組序列驗(yàn)證的時(shí)候,如果序列前邊的組驗(yàn)證失敗,則后面的組將不再給予驗(yàn)證。
下例中聲明了組 GroupA.class,GroupB.class 和 Group.class,其中 default,GroupA,GroupB 均為 Group 的序列。
public interface GroupA {
}
public interface GroupB {
}
@GroupSequence( { Default.class, GroupA.class, GroupB.class })
public interface Group {
}
public class User {
@NotEmpty(message = "firstname may be empty")
private String firstname;
@NotEmpty(message = "middlename may be empty", groups = Default.class)
private String middlename;
@NotEmpty(message = "lastname may be empty", groups = GroupA.class)
private String lastname;
@NotEmpty(message = "country may be empty", groups = GroupB.class)
private String country;
}
[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
@RequestMapping(value = "/update.action", method = RequestMethod.POST)
public String register(@Validated(Group.class) User user, BindingResult result) {
if (result.hasErrors()) {
return "validate/error";
}
return "redirect:/success";
}
3. 驗(yàn)證多個(gè)對(duì)象
當(dāng)我們?cè)谝粋€(gè)功能處理方法上需要驗(yàn)證多個(gè)模型對(duì)象時(shí),需要通過(guò)如下形式來(lái)獲取驗(yàn)證結(jié)果:
@RequestMapping("/validate/multi")
public String multi(@Valid @ModelAttribute("a") A a, BindingResult aErrors, @Valid @ModelAttribute("b") B b, BindingResult bErrors) {
if (aErrors.hasErrors()) { //如果a模型對(duì)象驗(yàn)證失敗
return "validate/error";
}
if (bErrors.hasErrors()) { //如果a模型對(duì)象驗(yàn)證失敗
return "validate/error";
}
return "redirect:/success";
}
每一個(gè)模型對(duì)象后邊都需要跟一個(gè)Errors或BindingResult對(duì)象來(lái)保存驗(yàn)證結(jié)果,其方法體內(nèi)部可以使用這兩個(gè)驗(yàn)證結(jié)果對(duì)象來(lái)選擇出錯(cuò)時(shí)跳轉(zhuǎn)的頁(yè)面或處理的邏輯。
4. Junit測(cè)試
當(dāng)自定義拓展Validation時(shí),可以使用如下方法進(jìn)行測(cè)試:
@Test
public void testValidate() {
AnnotationDescriptor<EqualsAny> descriptor = new AnnotationDescriptor<EqualsAny>(EqualsAny.class);
EqualsAny equalsAny = AnnotationFactory.create(descriptor);
EqualsAnyValidator equalsAnyValidator = new EqualsAnyValidator();
equalsAnyValidator.initialize(equalsAny);
Assert.assertTrue(equalsAnyValidator.isValid("123", null));
}
另外再講一點(diǎn)spring對(duì)自定義JSR-303限制類(lèi)型支持的新特性,那就是Spring支持往ConstraintValidator里面注入bean對(duì)象。例如在EqualsAnyValidator中利用@Resource注解注入其他Bean對(duì)象。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于Java日期工具類(lèi)的編寫(xiě)
這篇文章主要介紹了關(guān)于Java日期工具類(lèi)的編寫(xiě),在Java開(kāi)發(fā)中,經(jīng)常會(huì)遇到處理日期相關(guān)的數(shù)據(jù),那么今天我們來(lái)自己寫(xiě)一個(gè)工具類(lèi),文中有詳細(xì)的實(shí)例代碼以及實(shí)現(xiàn)思路,需要的朋友可以參考下2023-05-05
使用?mybatis?自定義日期類(lèi)型轉(zhuǎn)換器的示例代碼
這篇文章主要介紹了使用?mybatis?自定義日期類(lèi)型轉(zhuǎn)換器的示例代碼,這里使用mybatis中的typeHandlers?實(shí)現(xiàn)的,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-03-03
Spring?Boot異步線程間數(shù)據(jù)傳遞的四種方式
這篇文章主要為大家介紹了Spring?Boot異步線程間數(shù)據(jù)傳遞的四種方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
SpringBoot整合Mybatis實(shí)現(xiàn)高德地圖定位并將數(shù)據(jù)存入數(shù)據(jù)庫(kù)的步驟詳解
這篇文章主要介紹了SpringBoot整合Mybatis實(shí)現(xiàn)高德地圖定位并將數(shù)據(jù)存入數(shù)據(jù)庫(kù)的步驟詳解,本文分步驟通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
一步步講解Spring?Boot整合MyBatis與PostgreSQL實(shí)戰(zhàn)指南
這篇文章主要介紹了如何在SpringBoot環(huán)境中集成MyBatis和PostgreSQL,涵蓋了環(huán)境搭建、項(xiàng)目創(chuàng)建、數(shù)據(jù)源配置、實(shí)體類(lèi)與Mapper接口定義、MapperXML文件編寫(xiě)、業(yè)務(wù)層與控制層實(shí)現(xiàn)以及測(cè)試與驗(yàn)證的全過(guò)程,需要的朋友可以參考下2025-02-02
struts2如何使用攔截器進(jìn)行用戶權(quán)限控制實(shí)例
本篇文章主要介紹了struts2如何使用攔截器進(jìn)行用戶權(quán)限控制實(shí)例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05
解決springcloud啟動(dòng)時(shí)報(bào)錯(cuò)Connection refused:connect問(wèn)題
這篇文章主要介紹了解決springcloud啟動(dòng)時(shí)報(bào)錯(cuò)Connection refused:connect問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05

