SpringBoot?@GroupSequenceProvider注解實(shí)現(xiàn)bean多屬性聯(lián)合校驗(yàn)的示例代碼
參考資料
Hibernate Validator提供了非標(biāo)準(zhǔn)的
@GroupSequenceProvider注解。針對(duì)當(dāng)前對(duì)象實(shí)例的狀態(tài),動(dòng)態(tài)來(lái)決定加載那些校驗(yàn)組進(jìn)入默認(rèn)校驗(yàn)組。
需要借助Hibernate Validation提供給我們的DefaultGroupSequenceProvider接口來(lái)處理那些屬性在什么情況下進(jìn)入指定的分組。
一. 前期準(zhǔn)備
?自定義校驗(yàn)數(shù)值不能為空的注解
@Documented
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ValidateIntegerNotEmpty.StrictIntegerNotEmptyValidator.class})
@ReportAsSingleViolation
public @interface ValidateIntegerNotEmpty {
String msgArgs() default "";
String message() default "{1001E}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
class StrictIntegerNotEmptyValidator implements ConstraintValidator<ValidateIntegerNotEmpty, Integer> {
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return !ObjectUtils.isEmpty(value);
}
}
}
二. 需求
- 1 當(dāng)審核狀態(tài)為2(人工初審拒絕)的時(shí)候,審核拒絕原因?yàn)?strong>必填項(xiàng),并且范圍為1到4
- 當(dāng)審核狀態(tài)為2之外(審核中或者人工初審?fù)ㄟ^(guò))的情況,審核拒絕原因?yàn)?strong>非必填項(xiàng)
?前臺(tái)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<script type="text/javascript" th:src="@{/js/public/jquery-3.6.0.min.js}"></script>
<script type="text/javascript" th:src="@{/js/common/common.js}"></script>
<title>test7頁(yè)面</title>
</head>
<body>
<button id="btn">校驗(yàn)數(shù)據(jù)</button>
<h1>我是test7的頁(yè)面</h1>
</body>
<script>
$("#btn").click(() => {
const param1 = {
// 人工初審拒絕
auditStatus: 2,
// 拒絕的原因
auditRejectReason: 5,
};
const url = `http://localhost:8080/test7/groupSequenceProvider`;
doAjax(url, param1, function(data) {
console.log(data);
});
});
</script>
</html>?待校驗(yàn)的form1
import com.example.jmw.common.validation.ValidateIntegerNotEmpty;
import com.example.jmw.form.validation.ValidateTest7FormProvider;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.group.GroupSequenceProvider;
@Data
// 通過(guò)該注解所對(duì)應(yīng)的自定義Provider來(lái)實(shí)現(xiàn)多屬性聯(lián)合校驗(yàn)
@GroupSequenceProvider(ValidateTest7FormProvider.class)
public class Test7Form {
/**
* 1: 審核中
* 2: 人工初審拒絕
* 3: 人工初審?fù)ㄟ^(guò)
*/
@ValidateIntegerNotEmpty(msgArgs = "審核狀態(tài)類型")
@Range(min = 1, max = 3, message = "審核拒絕原因:參數(shù)傳遞錯(cuò)誤")
private Integer auditStatus;
/**
* 1: 不符合準(zhǔn)入要求
* 2: 三方數(shù)據(jù)拒貸
* 3: 授信額度為0
* 4: 其他
*/
@ValidateIntegerNotEmpty(msgArgs = "審核拒絕原因", groups = auditGroup.class)
@Range(min = 1, max = 4, message = "審核拒絕原因:參數(shù)傳遞錯(cuò)誤", groups = auditGroup.class)
private Integer auditRejectReason;
// 自定義分組
public interface auditGroup {
}
}
?校驗(yàn)器
import com.example.jmw.form.Test7Form;
import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class ValidateTest7FormProvider implements DefaultGroupSequenceProvider<Test7Form> {
@Override
public List<Class<?>> getValidationGroups(Test7Form test7Form) {
List<Class<?>> defaultGroupSequence = new ArrayList<>();
defaultGroupSequence.add(Test7Form.class);
if (ObjectUtils.isEmpty(test7Form)) {
return defaultGroupSequence;
}
// 獲取 人工初審 狀態(tài)
Integer auditStatus = Optional.ofNullable(test7Form.getAuditStatus()).orElse(0) ;
// 如果 人工初審?fù)ㄟ^(guò)的話,審核拒絕原因的auditGroup組就會(huì)起作用,就變?yōu)楸靥铐?xiàng)目,否則為選填項(xiàng)目
if (auditStatus == 2) {
defaultGroupSequence.add(Test7Form.auditGroup.class);
}
return defaultGroupSequence;
}
}
?Controller層進(jìn)行校驗(yàn)
@Controller
@RequestMapping("/test7")
public class Test7Controller {
@Resource
private LocalValidatorFactoryBean validator;
@GetMapping("/init")
public ModelAndView init() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("test7");
return modelAndView;
}
@PostMapping("/groupSequenceProvider")
@ResponseBody
public void groupSequenceProvider(@RequestBody Test7Form form) {
Set<ConstraintViolation<Test7Form>> validate = validator.validate(form);
for (ConstraintViolation<Test7Form> bean : validate) {
// 獲取當(dāng)前的校驗(yàn)信息
String message = bean.getMessage();
System.out.println(message);
}
}
}
當(dāng)參數(shù)auditStatus為2(人工初審拒絕)時(shí),auditRejectReason(審核拒絕原因)超出了1到4的范圍,因此顯示出校驗(yàn)信息

當(dāng)參數(shù)auditStatus為2(人工初審拒絕)時(shí),auditRejectReason(審核拒絕原因)為必填項(xiàng),因此顯示出校驗(yàn)信息

當(dāng)參數(shù)auditStatus為3(人工初審?fù)ㄟ^(guò))時(shí),auditRejectReason(審核拒絕原因)為非必填項(xiàng),因此無(wú)校驗(yàn)失敗信息

三. 需求
- 2 當(dāng)游客(1)訪問時(shí),最多有2個(gè)權(quán)限
- 當(dāng)領(lǐng)導(dǎo)(2)訪問時(shí),最多有4個(gè)權(quán)限
- 當(dāng)管理員(3)訪問時(shí),最多有10個(gè)權(quán)限
?前臺(tái)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<script type="text/javascript" th:src="@{/js/public/jquery-3.6.0.min.js}"></script>
<script type="text/javascript" th:src="@{/js/common/common.js}"></script>
<title>test7頁(yè)面</title>
</head>
<body>
<button id="btn">校驗(yàn)數(shù)據(jù)</button>
<h1>我是test7的頁(yè)面</h1>
</body>
<script>
$("#btn").click(() => {
const param2 = {
// 領(lǐng)導(dǎo)(2)訪問
role: 2,
// 權(quán)限的數(shù)量為5
permissionList: [1, 1, 1, 1, 1],
};
const url = `http://localhost:8080/test7/groupSequenceProvider`;
doAjax(url, param2, function(data) {
console.log(data);
});
});
</script>
</html>
?待校驗(yàn)的form2
import com.example.jmw.common.validation.ValidateIntegerNotEmpty;
import com.example.jmw.form.validation.ValidateTest7Form1Provider;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.group.GroupSequenceProvider;
import javax.validation.constraints.Size;
import java.util.List;
@Data
// 通過(guò)該注解所對(duì)應(yīng)的自定義Provider來(lái)實(shí)現(xiàn)多屬性聯(lián)合校驗(yàn)
@GroupSequenceProvider(ValidateTest7Form1Provider.class)
public class Test7Form1 {
/**
* 1: 訪客
* 2: 領(lǐng)導(dǎo)
* 3: 管理員
*/
@ValidateIntegerNotEmpty(msgArgs = "角色類型")
@Range(min = 1, max = 3, message = "錯(cuò)誤原因:參數(shù)傳遞錯(cuò)誤")
private Integer role;
@Size.List({
// 訪客1個(gè)權(quán)限
@Size(min = 1, max = 2, message = "訪客最多擁有2個(gè)權(quán)限", groups = GuestGroup.class),
// 領(lǐng)導(dǎo)4個(gè)權(quán)限
@Size(min = 1, max = 4, message = "領(lǐng)導(dǎo)最多擁有4個(gè)權(quán)限", groups = LeaderGroup.class),
// 管理員10個(gè)權(quán)限
@Size(min = 1, max = 10, message = "管理員最多擁有10個(gè)權(quán)限", groups = AdminGroup.class)
})
private List<Integer> permissionList;
// 游客分組
public interface GuestGroup {
}
// 領(lǐng)導(dǎo)分組
public interface LeaderGroup {
}
// 管理員分組
public interface AdminGroup {
}
}
?校驗(yàn)器
import com.example.jmw.form.Test7Form1;
import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider;
import org.springframework.util.ObjectUtils;
import java.util.*;
public class ValidateTest7Form1Provider implements DefaultGroupSequenceProvider<Test7Form1> {
/**
* 1: 訪客
* 2: 領(lǐng)導(dǎo)
* 3: 管理員
*/
private final static List<Integer> roleList = Arrays.asList(1, 2, 3);
@Override
public List<Class<?>> getValidationGroups(Test7Form1 test7Form1) {
List<Class<?>> defaultGroupSequence = new ArrayList<>();
defaultGroupSequence.add(Test7Form1.class);
if (ObjectUtils.isEmpty(test7Form1)) {
return defaultGroupSequence;
}
// 獲取角色code
Integer role = Optional.ofNullable(test7Form1.getRole()).orElse(0) ;
if (!roleList.contains(role)) {
return defaultGroupSequence;
}
// 根據(jù)角色code,開啟相應(yīng)的組校驗(yàn)
if (role == 1) {
defaultGroupSequence.add(Test7Form1.GuestGroup.class);
} else if (role == 2) {
defaultGroupSequence.add(Test7Form1.LeaderGroup.class);
} else if (role == 3) {
defaultGroupSequence.add(Test7Form1.AdminGroup.class);
}
return defaultGroupSequence;
}
}
?Controller層進(jìn)行校驗(yàn)
@Controller
@RequestMapping("/test7")
public class Test7Controller {
@Resource
private LocalValidatorFactoryBean validator;
@GetMapping("/init")
public ModelAndView init() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("test7");
return modelAndView;
}
@PostMapping("/groupSequenceProvider")
@ResponseBody
public void groupSequenceProvider(@RequestBody Test7Form1 form) {
Set<ConstraintViolation<Test7Form1>> validate = validator.validate(form);
for (ConstraintViolation<Test7Form1> bean : validate) {
// 獲取當(dāng)前的校驗(yàn)信息
String message = bean.getMessage();
System.out.println(message);
}
}
}
當(dāng)角色為2(領(lǐng)導(dǎo))時(shí),最多只能有4個(gè)權(quán)限,因此顯示校驗(yàn)信息

當(dāng)角色為1(訪客)時(shí),最多只能有2個(gè)權(quán)限,因此顯示校驗(yàn)信息

當(dāng)角色為3(管理員)時(shí),最多有10個(gè)權(quán)限,因此無(wú)校驗(yàn)信息

到此這篇關(guān)于SpringBoot @GroupSequenceProvider注解實(shí)現(xiàn)bean多屬性聯(lián)合校驗(yàn)的文章就介紹到這了,更多相關(guān)SpringBoot聯(lián)合校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot?使用?Sa-Token?完成注解鑒權(quán)功能(權(quán)限校驗(yàn))
- SpringBoot通過(guò)自定義注解實(shí)現(xiàn)參數(shù)校驗(yàn)
- SpringBoot通過(guò)AOP與注解實(shí)現(xiàn)入?yún)⑿r?yàn)詳情
- SpringBoot常見get/post請(qǐng)求參數(shù)處理、參數(shù)注解校驗(yàn)及參數(shù)自定義注解校驗(yàn)詳解
- SpringBoot中@Pattern注解對(duì)時(shí)間格式校驗(yàn)方式
- SpringBoot自定義注解API數(shù)據(jù)加密和簽名校驗(yàn)
- SpringBoot中自定義注解實(shí)現(xiàn)參數(shù)非空校驗(yàn)的示例
- SpringBoot @Validated注解實(shí)現(xiàn)參數(shù)分組校驗(yàn)的方法實(shí)例
- springboot自定義校驗(yàn)注解的實(shí)現(xiàn)過(guò)程
相關(guān)文章
手把手教你寫Maven的archetype項(xiàng)目腳手架
本文主要介紹了Maven的archetype項(xiàng)目腳手架,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
Spring Junit測(cè)試找不到SpringJUnit4ClassRunner.class的解決
這篇文章主要介紹了Spring Junit測(cè)試找不到SpringJUnit4ClassRunner.class的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
springboot編程式事務(wù)TransactionTemplate的使用說(shuō)明
這篇文章主要介紹了springboot編程式事務(wù)TransactionTemplate的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
springboot整合mybatis中的問題及出現(xiàn)的一些問題小結(jié)
這篇文章主要介紹了springboot整合mybatis中的問題及出現(xiàn)的一些問題小結(jié),本文給出了解決方案,需要的朋友可以參考下2018-11-11
VScode 打造完美java開發(fā)環(huán)境最新教程
這篇文章主要介紹了VScode 打造完美java開發(fā)環(huán)境最新教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
使用springboot的jar包能夠以service方式啟動(dòng)
這篇文章主要介紹了使用springboot的jar包能夠以service方式啟動(dòng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
js判斷是否是移動(dòng)設(shè)備登陸網(wǎng)頁(yè)的簡(jiǎn)單方法
這篇文章主要介紹了js判斷是否是移動(dòng)設(shè)備登陸網(wǎng)頁(yè)的簡(jiǎn)單方法,需要的朋友可以參考下2014-02-02
java實(shí)現(xiàn)oracle插入當(dāng)前時(shí)間的方法
這篇文章主要介紹了java實(shí)現(xiàn)oracle插入當(dāng)前時(shí)間的方法,以實(shí)例形式對(duì)比分析了java使用Oracle操作時(shí)間的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03

