Java的validation參數(shù)校驗(yàn)代碼實(shí)例
bean validation和hibernate validator參數(shù)校驗(yàn)
常用注解
@Null(groups={Add.class}) 參數(shù)必須為null,group設(shè)置分組,默認(rèn)為default
@NotNull 參數(shù)不為null
@NotEmpty 參數(shù)不為null ,"",集合不為空
@NotBlank 參數(shù)不為null, "", " ",只能作用字符串類型
@AssertFalse 被注釋的元素必須是false
@AssertTrue 被注釋的元素必須是true
@Min(value) 被注釋的元素必須為一個(gè)數(shù)字 >=
@Max(value) 被注釋的元素必須為一個(gè)數(shù)字 <=
@DecimalMin("value") >=
@DecimalMax("value") <=
@NegativeOrZero <=0
@Range(min,max) 被注釋的元素大小必須在指定的范圍內(nèi)
@Size(min ,max) 被注釋的元素大小必須在指定的范圍內(nèi)
@Email 被注釋的元素必須是電子郵箱地址
@Past 被注釋的元素必須是一個(gè)過(guò)去的日期
@PastOrPresent 被注釋的元素必須是一個(gè)過(guò)去的時(shí)間
@Future 被注釋的元素必須是一個(gè)將來(lái)的日期
@Pattern(regexp = "1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$") 被注釋的元素必須是符合指定的正則表達(dá)式
@URL 被注釋的元素必須是鏈接地址
備注:參數(shù)校驗(yàn)只有!= null的時(shí)候才生效1.導(dǎo)入依賴
<!--引入hibernate-validator,beanvalidator-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
<!--el規(guī)范和tomcat的實(shí)現(xiàn),用于解析message里面的表達(dá)式-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>9.0.29</version>
</dependency>springboot依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
2.測(cè)試
//1.定義實(shí)體類
@Data
public class UserInfo{
@NotBlank
private String name;
}
//2.編寫工具類
public class UserInfo{
//聲明validator,線程安全的:所有的方法都可以使用這個(gè)對(duì)象,而不會(huì)產(chǎn)生線程安全的問(wèn)題
private static Validator validator;
//初始化默認(rèn)的validator對(duì)象
static {validator = Validation.buildDefaultValidatorFactory().getValidator();}
//校驗(yàn)
public static List<String> valid(UserInfo userInfo,Class<?>... groups){
//如果被校驗(yàn)對(duì)象userInfo沒(méi)有檢驗(yàn)通過(guò),則set里面就有校驗(yàn)信息,返回出去
Set<ConstraintViolation<UserInfo>> set = validator.validate(userInfo,groups);
List<String> list = set.stream().map(v -> "屬性:" + v.getPropertyPath() + ",屬性值是:" + v.getInvalidValue()
+ ",校驗(yàn)不通過(guò)的提示信息:" + v.getMessage()+",消息模板:"+v.getMessageTemplate()).collect(Collectors.toList());
return list;
}
}
//3.測(cè)試
public class ValidationTest {
public static void main(String[] args) {
UserInfo info = new UserInfo();
info.setName("名字");
}
List<String> valid1 = ValidationUtil.valid(info);
System.out.println(valid1);
//返回結(jié)果:
[屬性:name,屬性值是:null,校驗(yàn)不通過(guò)的提示信息:不能為空,消息模板:{javax.validation.constraints.NotBlank.message}]
3.自定義消息模板
@NotBlank(message = "姓名不能為空!!") private String name;
返回結(jié)果:
[屬性:name,屬性值是:null,校驗(yàn)不通過(guò)的提示信息:姓名不能為空??!,消息模板:姓名不能為空?。
4.分組校驗(yàn)
//1.定義實(shí)體類
public class UserInfo{
//標(biāo)記接口 新增,修改,刪除
public interface Add extends Default {}
public interface Update extends Default{}
public interface Delete extends Default{}
//默認(rèn)組default,指定分組
@Null(groups = {Add.class}) //只適用于新增
@NotNull(groups = {Update.class,Delete.class})//只適用于修改/刪除
private Long id;
@NotBlank(message = "姓名不能為空??!")
private String name;}
//2.編寫工具類
//校驗(yàn),要檢驗(yàn)的對(duì)象,檢驗(yàn)分組
public static List<String> valid(UserInfo userInfo,Class<?>... groups){
//如果被校驗(yàn)對(duì)象userInfo沒(méi)有檢驗(yàn)通過(guò),則2set里面就有校驗(yàn)信息,返回出去
Set<ConstraintViolation<UserInfo>> set = validator.validate(userInfo,groups);
List<String> list = set.stream().map(v -> "屬性:" + v.getPropertyPath() + ",屬性值是:" + v.getInvalidValue()
+ ",校驗(yàn)不通過(guò)的提示信息:" + v.getMessage()+",消息模板:"+v.getMessageTemplate()).collect(Collectors.toList());
return list;
}
//3.測(cè)試
public class ValidationTest {
public static void main(String[] args) {
UserInfo info = new UserInfo();
info.setName("名字");
}
List<String> valid1 = ValidationUtil.valid(info,UserInfo.Add.class);
List<String> valid2 = ValidationUtil.valid(info,UserInfo.Update.class);
System.out.println(valid1);
System.out.println(valid2);//結(jié)果
valid1[]
valid1[屬性:id,屬性值是:null,校驗(yàn)不通過(guò)的提示信息:不能為null,消息模板:{javax.validation.constraints.NotNull.message}]
5.級(jí)聯(lián)校驗(yàn)
//1.編寫實(shí)體類
public class UserInfo{
@NotBlank(message = "姓名不能為空!!")
private String name;
@Valid //被引用對(duì)象加上@valid注解,才可以完成級(jí)聯(lián)校驗(yàn)
private Grade grade;
}
public class Grade {
@NotBlank
private String id;
}
//2.工具類同上
//3.測(cè)試
public class ValidationTest {
public static void main(String[] args) {
UserInfo info = new UserInfo();
info.setName("名字");
//添加grade
Grade grade = new Grade();
//grade.setId("123");
info.setGrade(grade);
}
//結(jié)果
valid1[屬性:grade.id,屬性值是:null,校驗(yàn)不通過(guò)的提示信息:不能為空,消息模板:{javax.validation.constraints.NotBlank.message}]
6.自定義注解
status的必須為1000/1001/1002
//1.編寫實(shí)體類
public class UserInfo{
@NotBlank(message = "姓名不能為空??!")
private String name;
@UserStatus
private Integer status;
}
//2.1編寫注解要校驗(yàn)的規(guī)則
-繼承ConstraintValidator<UserStatus,Integer>,綁定要校驗(yàn)的約束注解UserStatus,類型
public class UserStatusValidator implements ConstraintValidator<UserStatus,Integer> {
@Override
public void initialize(UserStatus constraintAnnotation) {
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
if (value == null){
//沒(méi)有值,不校驗(yàn)
return true;
}
//設(shè)置要求之
Set<Integer> set = new HashSet<>();
set.add(1000);
set.add(1001);
set.add(1002);
return set.contains(value);
}
}
//2.2編寫注解聲明類
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {UserStatusValidator.class})//說(shuō)明當(dāng)前注解要被誰(shuí)來(lái)完成校驗(yàn)工作
@Documented
public @interface UserStatus {
String message() default "{userStatus必須是1000/1001/1002}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
//3.測(cè)試
public class ValidationTest {
public static void main(String[] args) {
UserInfo info = new UserInfo();
info.setName("名字");
info.setStatus(200);
List<String> valid1 = ValidationUtil.valid(info);
System.out.println("valid1"+valid1);
}
//結(jié)果
valid1[屬性:status,屬性值是:200,校驗(yàn)不通過(guò)的提示信息:{userStatus必須是1000/1001/1002},消息模板:{userStatus必須是1000/1001/1002}, 屬性:grade,屬性值是:null,校驗(yàn)不通過(guò)的提示信息:不能為空,消息模板:{org.hibernate.validator.constraints.NotEmpty.message}]
7.快速校驗(yàn)
//1.實(shí)體類 同上
//2.工具類
public class ValidationUtil {
//配置快速失敗
private static Validator validFailFast;
static {
validFailFast = Validation.byProvider(HibernateValidator.class).configure()
.failFast(true).buildValidatorFactory().getValidator();//.failFast(true),快速失敗
}
public static<T> List<String> validNotBean(T object, Method method, Object[] parameterValues, Class<?>... groups){
Set<ConstraintViolation<T>> set = executables.validateParameters(object, method, parameterValues, groups);
List<String> list = set.stream().map(v -> "屬性:" + v.getPropertyPath() + ",屬性值是:" + v.getInvalidValue()
+ ",校驗(yàn)不通過(guò)的提示信息:" + v.getMessage()+",消息模板:"+v.getMessageTemplate()).collect(Collectors.toList());
return list;
}
// 3.測(cè)試類同上
// 調(diào)用:
List<String> valid = ValidationUtil.validFailFast(info,UserInfo.Add.class);
// 效果:當(dāng)有錯(cuò)誤時(shí),直接返回第一個(gè)錯(cuò)誤,不再校驗(yàn)其他錯(cuò)誤。8.非bean入?yún)⑿r?yàn)
請(qǐng)求參數(shù)和返回值并不是一個(gè)bean
//1.編寫要校驗(yàn)的方法
/**
* 方法非bean類型的入?yún)⑿r?yàn)
* 1.方法參數(shù)前加注解
* 2.執(zhí)行入?yún)⑿r?yàn),真正有用的話可以使用aop編程思想來(lái)使用
*/
public String getByName(@NotBlank String name){
//執(zhí)行入?yún)⑿r?yàn)
//當(dāng)前線程的堆棧,第一個(gè)元素就是當(dāng)前所在方法的名字
StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[1];
String methodName = stackTraceElement.getMethodName();
Method method = null;
try{
method = this.getClass().getDeclaredMethod(methodName, String.class);
}catch (Exception e) {
e.printStackTrace();
}
List<String> strings = ValidationUtil.validNotBean(this, method, new Object[]{name});
//打印校驗(yàn)結(jié)果
System.out.println("校驗(yàn)結(jié)果:" + strings);
return "ok";
}
//2.工具類編寫
public class ValidationUtil {
private static ExecutableValidator executables;
static {
validator = Validation.buildDefaultValidatorFactory().getValidator();
//校驗(yàn)入?yún)⒒蚍祷刂档?
executables = validator.forExecutables();
}
public static<T> List<String> validNotBean(T object, Method method, Object[] parameterValues, Class<?>... groups){
//校驗(yàn)方法參數(shù) validateParameters
Set<ConstraintViolation<T>> set = executables.validateParameters(object, method, parameterValues, groups);
List<String> list = set.stream().map(v -> "屬性:" + v.getPropertyPath() + ",屬性值是:" + v.getInvalidValue()
+ ",校驗(yàn)不通過(guò)的提示信息:" + v.getMessage()+",消息模板:"+v.getMessageTemplate()).collect(Collectors.toList());
return list;
}
}
//3.測(cè)試
method.getByName("");返回結(jié)果
校驗(yàn)結(jié)果:[屬性:getByName.arg0,屬性值是:,校驗(yàn)不通過(guò)的提示信息:不能為空,消息模板:{javax.validation.constraints.NotBlank.message}]
9.與SpringBoot整合
1.編程式校驗(yàn)
直接使用工具類校驗(yàn)
@GetMapping("/addUser")
public String getByName(UserInfo userInfo){
List<String> valid = ValidationUtil.valid(userInfo);
if (valid.size()>0){
System.out.println(valid);
return "校驗(yàn)不成功";
}else {
return "添加成功!";}
}訪問(wèn):http:8080/addUser
結(jié)果:校驗(yàn)不成功 控制臺(tái)打印報(bào)錯(cuò)
2.聲明式校驗(yàn)
@GetMapping("/addUser2")
public String getByName2(@Valid UserInfo userInfo){
return "添加成功";}
//結(jié)果:頁(yè)面直接報(bào)錯(cuò)
//將校驗(yàn)結(jié)果封裝到BindingResult,不會(huì)頁(yè)面上報(bào)錯(cuò)
@GetMapping("/addUser2")
public String getByName2(@Valid UserInfo userInfo, BindingResult result){
if(result.hasErrors()){//判斷是否有不滿足約束的
List<ObjectError> errors = result.getAllErrors();
for (ObjectError error : errors) {
//打印錯(cuò)誤信息
System.out.println(error.getObjectName()+"::"+error.getDefaultMessage());
}
//獲取沒(méi)通過(guò)校驗(yàn)的字段詳情
List<FieldError> fieldErrorList = result.getFieldErrors();
for (FieldError fieldError : fieldErrorList) {
System.out.println(fieldError.getField() + "::" + fieldError.getDefaultMessage() + ",當(dāng)前沒(méi)有通過(guò)校驗(yàn)規(guī)則的值是:" + fieldError.getRejectedValue());
}
};
return "添加成功";
}3.@Validated 實(shí)現(xiàn)分組校驗(yàn)
@GetMapping("/addUser3")
public String getByName3(@Validated(value = {UserInfo.Add.class}) UserInfo userInfo, BindingResult result){
if(result.hasErrors()){//判斷是否有不滿足約束的
List<ObjectError> errors = result.getAllErrors();
for (ObjectError error : errors) {
System.out.println(error.getObjectName()+"::"+error.getDefaultMessage());
}
//獲取沒(méi)通過(guò)校驗(yàn)的字段詳情
List<FieldError> fieldErrorList = result.getFieldErrors();
for (FieldError fieldError : fieldErrorList) {
System.out.println(fieldError.getField() + "::" + fieldError.getDefaultMessage() + ",當(dāng)前沒(méi)有通過(guò)校驗(yàn)規(guī)則的值是:" + fieldError.getRejectedValue());
}
};
return "添加成功";
}@Validated方法參數(shù)校驗(yàn)
@Validated//表示整個(gè)類都啟用校驗(yàn),如果碰到入?yún)⒑衎ean validation注解的話就會(huì)自動(dòng)校驗(yàn)
@GetMapping("/getByName")
public String getByName(@NotBlank String name){
return name;
}10.統(tǒng)一異常處理
不寫B(tài)indingResult result
方式一:添加一個(gè)方法,使用@ExceptionHandler(BindException.class)標(biāo)記,處理當(dāng)前controller里拋出的xx異常
@ExceptionHandler(BindException.class)
public String handleEx(BindException e){
List<FieldError> fieldErrors = e.getFieldErrors();
StringBuilder builder = new StringBuilder();
for (FieldError fieldError : fieldErrors) {
builder.append("屬性:").append(fieldError.getField()).append("校驗(yàn)不通過(guò)的原因:").append(fieldError.getDefaultMessage()).append(";;");
}
return builder.toString();
}方式二:編寫統(tǒng)一的異常處理方式
@ControllerAdvice
public class RoadControllerAdvice {
/**
*@Validated 寫在方法上的時(shí)候會(huì)報(bào)這個(gè)異常
*/
@ExceptionHandler(BindException.class)
@ResponseBody
public String handleEx(BindException e){
List<FieldError> fieldErrors = e.getFieldErrors();
StringBuilder builder = new StringBuilder("RoadControllerAdvice里的:");
for (FieldError fieldError : fieldErrors) {
builder.append("屬性:").append(fieldError.getField()).append("校驗(yàn)不通過(guò)的原因:").append(fieldError.getDefaultMessage()).append(";;");
}
return builder.toString();
}
/**
* @Validated 寫在類上的時(shí)候會(huì)報(bào)這個(gè)異常
*/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public List<String> handleEx(ConstraintViolationException e){
Set<ConstraintViolation<?>> fieldErrors = e.getConstraintViolations();
StringBuilder builder = new StringBuilder("RoadControllerAdvice里的:");
List<String> list = fieldErrors.stream().map(v -> "屬性:" + v.getPropertyPath() + ",屬性值是:" + v.getInvalidValue()
+ ",校驗(yàn)不通過(guò)的提示信息:" + v.getMessage()+",消息模板:"+v.getMessageTemplate()).collect(Collectors.toList());
return list;
}
/**
* 處理所有異常信息
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public String handleEx(Exception e){
return e.getMessage();
}
}到此這篇關(guān)于Java的validation參數(shù)校驗(yàn)代碼實(shí)例的文章就介紹到這了,更多相關(guān)validation參數(shù)校驗(yàn)代碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決maven build 無(wú)反應(yīng),直接terminated的問(wèn)題
下面小編就為大家?guī)?lái)一篇解決maven build 無(wú)反應(yīng),直接terminated的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
Mybatis/Mybatis-Plus駝峰式命名映射的實(shí)現(xiàn)
本文主要介紹了Mybatis-Plus駝峰式命名映射的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Java項(xiàng)目之java+springboot+ssm實(shí)現(xiàn)理財(cái)管理系統(tǒng)設(shè)計(jì)
這篇文章主要介紹了Java項(xiàng)目java+springboot+ssm實(shí)現(xiàn)理財(cái)管理系統(tǒng)設(shè)計(jì),使用了當(dāng)前較為流行的spring boot,spring,spring mvc,mybatis,shiro框架分頁(yè)處理使用了pagehelper進(jìn)行操作,需要的朋友可以參考一下2022-03-03
基于XML配置Spring的自動(dòng)裝配過(guò)程解析
這篇文章主要介紹了基于XML配置Spring的自動(dòng)裝配過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
Java中Timer的schedule()方法參數(shù)詳解
今天小編就為大家分享一篇關(guān)于Java中Timer的schedule()方法參數(shù)詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
Java詳細(xì)分析講解自動(dòng)裝箱自動(dòng)拆箱與Integer緩存的使用
裝箱就是把基本類型轉(zhuǎn)換成包裝類,拆箱就是把包裝類轉(zhuǎn)換成基本類型,下面這篇文章主要給大家介紹Java中自動(dòng)裝箱、自動(dòng)拆箱與Integer緩存,需要的朋友可以參考下2022-04-04
Java中Easypoi實(shí)現(xiàn)excel多sheet表導(dǎo)入導(dǎo)出功能
這篇文章主要介紹了Java中Easypoi實(shí)現(xiàn)excel多sheet表導(dǎo)入導(dǎo)出功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

