Java的validation參數(shù)校驗代碼實例
bean validation和hibernate validator參數(shù)校驗
常用注解
@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) 被注釋的元素必須為一個數(shù)字 >= @Max(value) 被注釋的元素必須為一個數(shù)字 <= @DecimalMin("value") >= @DecimalMax("value") <= @NegativeOrZero <=0 @Range(min,max) 被注釋的元素大小必須在指定的范圍內(nèi) @Size(min ,max) 被注釋的元素大小必須在指定的范圍內(nèi) @Email 被注釋的元素必須是電子郵箱地址 @Past 被注釋的元素必須是一個過去的日期 @PastOrPresent 被注釋的元素必須是一個過去的時間 @Future 被注釋的元素必須是一個將來的日期 @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}$") 被注釋的元素必須是符合指定的正則表達式 @URL 被注釋的元素必須是鏈接地址 備注:參數(shù)校驗只有!= null的時候才生效
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的實現(xiàn),用于解析message里面的表達式--> <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.測試
//1.定義實體類 @Data public class UserInfo{ @NotBlank private String name; } //2.編寫工具類 public class UserInfo{ //聲明validator,線程安全的:所有的方法都可以使用這個對象,而不會產(chǎn)生線程安全的問題 private static Validator validator; //初始化默認(rèn)的validator對象 static {validator = Validation.buildDefaultValidatorFactory().getValidator();} //校驗 public static List<String> valid(UserInfo userInfo,Class<?>... groups){ //如果被校驗對象userInfo沒有檢驗通過,則set里面就有校驗信息,返回出去 Set<ConstraintViolation<UserInfo>> set = validator.validate(userInfo,groups); List<String> list = set.stream().map(v -> "屬性:" + v.getPropertyPath() + ",屬性值是:" + v.getInvalidValue() + ",校驗不通過的提示信息:" + v.getMessage()+",消息模板:"+v.getMessageTemplate()).collect(Collectors.toList()); return list; } } //3.測試 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,校驗不通過的提示信息:不能為空,消息模板:{javax.validation.constraints.NotBlank.message}]
3.自定義消息模板
@NotBlank(message = "姓名不能為空?。?) private String name;
返回結(jié)果:
[屬性:name,屬性值是:null,校驗不通過的提示信息:姓名不能為空!!,消息模板:姓名不能為空??!]
4.分組校驗
//1.定義實體類 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.編寫工具類 //校驗,要檢驗的對象,檢驗分組 public static List<String> valid(UserInfo userInfo,Class<?>... groups){ //如果被校驗對象userInfo沒有檢驗通過,則2set里面就有校驗信息,返回出去 Set<ConstraintViolation<UserInfo>> set = validator.validate(userInfo,groups); List<String> list = set.stream().map(v -> "屬性:" + v.getPropertyPath() + ",屬性值是:" + v.getInvalidValue() + ",校驗不通過的提示信息:" + v.getMessage()+",消息模板:"+v.getMessageTemplate()).collect(Collectors.toList()); return list; } //3.測試 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,校驗不通過的提示信息:不能為null,消息模板:{javax.validation.constraints.NotNull.message}]
5.級聯(lián)校驗
//1.編寫實體類 public class UserInfo{ @NotBlank(message = "姓名不能為空??!") private String name; @Valid //被引用對象加上@valid注解,才可以完成級聯(lián)校驗 private Grade grade; } public class Grade { @NotBlank private String id; } //2.工具類同上 //3.測試 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,校驗不通過的提示信息:不能為空,消息模板:{javax.validation.constraints.NotBlank.message}]
6.自定義注解
status的必須為1000/1001/1002
//1.編寫實體類 public class UserInfo{ @NotBlank(message = "姓名不能為空?。?) private String name; @UserStatus private Integer status; } //2.1編寫注解要校驗的規(guī)則 -繼承ConstraintValidator<UserStatus,Integer>,綁定要校驗的約束注解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){ //沒有值,不校驗 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})//說明當(dāng)前注解要被誰來完成校驗工作 @Documented public @interface UserStatus { String message() default "{userStatus必須是1000/1001/1002}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } //3.測試 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,校驗不通過的提示信息:{userStatus必須是1000/1001/1002},消息模板:{userStatus必須是1000/1001/1002}, 屬性:grade,屬性值是:null,校驗不通過的提示信息:不能為空,消息模板:{org.hibernate.validator.constraints.NotEmpty.message}]
7.快速校驗
//1.實體類 同上 //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() + ",校驗不通過的提示信息:" + v.getMessage()+",消息模板:"+v.getMessageTemplate()).collect(Collectors.toList()); return list; } // 3.測試類同上 // 調(diào)用: List<String> valid = ValidationUtil.validFailFast(info,UserInfo.Add.class); // 效果:當(dāng)有錯誤時,直接返回第一個錯誤,不再校驗其他錯誤。
8.非bean入?yún)⑿r?/h3>
請求參數(shù)和返回值并不是一個bean
//1.編寫要校驗的方法 /** * 方法非bean類型的入?yún)⑿r? * 1.方法參數(shù)前加注解 * 2.執(zhí)行入?yún)⑿r?,真正有用的話可以使用aop編程思想來使用 */ public String getByName(@NotBlank String name){ //執(zhí)行入?yún)⑿r? //當(dāng)前線程的堆棧,第一個元素就是當(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}); //打印校驗結(jié)果 System.out.println("校驗結(jié)果:" + strings); return "ok"; } //2.工具類編寫 public class ValidationUtil { private static ExecutableValidator executables; static { validator = Validation.buildDefaultValidatorFactory().getValidator(); //校驗入?yún)⒒蚍祷刂档? executables = validator.forExecutables(); } public static<T> List<String> validNotBean(T object, Method method, Object[] parameterValues, Class<?>... groups){ //校驗方法參數(shù) validateParameters Set<ConstraintViolation<T>> set = executables.validateParameters(object, method, parameterValues, groups); List<String> list = set.stream().map(v -> "屬性:" + v.getPropertyPath() + ",屬性值是:" + v.getInvalidValue() + ",校驗不通過的提示信息:" + v.getMessage()+",消息模板:"+v.getMessageTemplate()).collect(Collectors.toList()); return list; } } //3.測試 method.getByName("");
返回結(jié)果
校驗結(jié)果:[屬性:getByName.arg0,屬性值是:,校驗不通過的提示信息:不能為空,消息模板:{javax.validation.constraints.NotBlank.message}]
9.與SpringBoot整合
1.編程式校驗
直接使用工具類校驗 @GetMapping("/addUser") public String getByName(UserInfo userInfo){ List<String> valid = ValidationUtil.valid(userInfo); if (valid.size()>0){ System.out.println(valid); return "校驗不成功"; }else { return "添加成功!";} }
訪問:http:8080/addUser
結(jié)果:校驗不成功 控制臺打印報錯
2.聲明式校驗
@GetMapping("/addUser2") public String getByName2(@Valid UserInfo userInfo){ return "添加成功";} //結(jié)果:頁面直接報錯 //將校驗結(jié)果封裝到BindingResult,不會頁面上報錯 @GetMapping("/addUser2") public String getByName2(@Valid UserInfo userInfo, BindingResult result){ if(result.hasErrors()){//判斷是否有不滿足約束的 List<ObjectError> errors = result.getAllErrors(); for (ObjectError error : errors) { //打印錯誤信息 System.out.println(error.getObjectName()+"::"+error.getDefaultMessage()); } //獲取沒通過校驗的字段詳情 List<FieldError> fieldErrorList = result.getFieldErrors(); for (FieldError fieldError : fieldErrorList) { System.out.println(fieldError.getField() + "::" + fieldError.getDefaultMessage() + ",當(dāng)前沒有通過校驗規(guī)則的值是:" + fieldError.getRejectedValue()); } }; return "添加成功"; }
3.@Validated 實現(xià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()); } //獲取沒通過校驗的字段詳情 List<FieldError> fieldErrorList = result.getFieldErrors(); for (FieldError fieldError : fieldErrorList) { System.out.println(fieldError.getField() + "::" + fieldError.getDefaultMessage() + ",當(dāng)前沒有通過校驗規(guī)則的值是:" + fieldError.getRejectedValue()); } }; return "添加成功"; }
@Validated方法參數(shù)校驗
@Validated//表示整個類都啟用校驗,如果碰到入?yún)⒑衎ean validation注解的話就會自動校驗 @GetMapping("/getByName") public String getByName(@NotBlank String name){ return name; }
10.統(tǒng)一異常處理
不寫B(tài)indingResult result
方式一:添加一個方法,使用@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("校驗不通過的原因:").append(fieldError.getDefaultMessage()).append(";;"); } return builder.toString(); }
方式二:編寫統(tǒng)一的異常處理方式
@ControllerAdvice public class RoadControllerAdvice { /** *@Validated 寫在方法上的時候會報這個異常 */ @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("校驗不通過的原因:").append(fieldError.getDefaultMessage()).append(";;"); } return builder.toString(); } /** * @Validated 寫在類上的時候會報這個異常 */ @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() + ",校驗不通過的提示信息:" + 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ù)校驗代碼實例的文章就介紹到這了,更多相關(guān)validation參數(shù)校驗代碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決maven build 無反應(yīng),直接terminated的問題
下面小編就為大家?guī)硪黄鉀Qmaven build 無反應(yīng),直接terminated的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06Mybatis/Mybatis-Plus駝峰式命名映射的實現(xiàn)
本文主要介紹了Mybatis-Plus駝峰式命名映射的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Java項目之java+springboot+ssm實現(xiàn)理財管理系統(tǒng)設(shè)計
這篇文章主要介紹了Java項目java+springboot+ssm實現(xiàn)理財管理系統(tǒng)設(shè)計,使用了當(dāng)前較為流行的spring boot,spring,spring mvc,mybatis,shiro框架分頁處理使用了pagehelper進行操作,需要的朋友可以參考一下2022-03-03Java中Timer的schedule()方法參數(shù)詳解
今天小編就為大家分享一篇關(guān)于Java中Timer的schedule()方法參數(shù)詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03Java詳細(xì)分析講解自動裝箱自動拆箱與Integer緩存的使用
裝箱就是把基本類型轉(zhuǎn)換成包裝類,拆箱就是把包裝類轉(zhuǎn)換成基本類型,下面這篇文章主要給大家介紹Java中自動裝箱、自動拆箱與Integer緩存,需要的朋友可以參考下2022-04-04Java中Easypoi實現(xiàn)excel多sheet表導(dǎo)入導(dǎo)出功能
這篇文章主要介紹了Java中Easypoi實現(xiàn)excel多sheet表導(dǎo)入導(dǎo)出功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01