Java中JSR303的基本使用詳情
1.關(guān)于JSR-303
JSR-303規(guī)范(Bean Validation規(guī)范)提供了對(duì) Java EE 和 Java SE 中的 Java Bean 進(jìn)行驗(yàn)證的方式。該規(guī)范主要使用注解的方式來實(shí)現(xiàn)對(duì) Java Bean 的驗(yàn)證功能 。
Hibernate Validator 提供了 JSR 303 規(guī)范中所有內(nèi)置 constraint 的實(shí)現(xiàn),除此之外還有一些附加的 constraint。官方文檔
Bean Validation 中內(nèi)置的 constraint:
| 約束注解名稱 | ** 約束注解說明** |
|---|---|
| @Null | 驗(yàn)證對(duì)象是否為空 |
| @NotNull | 驗(yàn)證對(duì)象是否為非空 |
| @AssertTrue | 驗(yàn)證 Boolean 對(duì)象是否為 true |
| @AssertFalse | 驗(yàn)證 Boolean 對(duì)象是否為 false |
| @Min | 驗(yàn)證 Number 和 String 對(duì)象是否大等于指定的值 |
| @Max | 驗(yàn)證 Number 和 String 對(duì)象是否小等于指定的值 |
| @DecimalMin | 驗(yàn)證 Number 和 String 對(duì)象是否大等于指定的值,小數(shù)存在精度 |
| @DecimalMax | 驗(yàn)證 Number 和 String 對(duì)象是否小等于指定的值,小數(shù)存在精度 |
| @Size | 驗(yàn)證對(duì)象(Array,Collection,Map,String)長度是否在給定的范圍之內(nèi) |
| @Digits | 驗(yàn)證 Number 和 String 的構(gòu)成是否合法 |
| @Past | 驗(yàn)證 Date 和 Calendar 對(duì)象是否在當(dāng)前時(shí)間之前 |
| @Future | 驗(yàn)證 Date 和 Calendar 對(duì)象是否在當(dāng)前時(shí)間之后 |
| @Pattern | 驗(yàn)證 String 對(duì)象是否符合正則表達(dá)式的規(guī)則 |
2. 基本使用
- 在參數(shù)上加上校驗(yàn)注解,如果參數(shù)是自定義類型,則在類的屬性上加校驗(yàn)注解。
- 使校驗(yàn)注解生效
- 2.1 直接在參數(shù)上加校驗(yàn)注解,需要在類上加
@Validated - 2.1 自定義類型,變量前面加
@Validated或者@Valid
- 2.1 直接在參數(shù)上加校驗(yàn)注解,需要在類上加
@Data
public class Emp {
//不能為空且不能為空串
@NotBlank(message = "賬號(hào)不能為空")
private String username;
}
@PostMapping("/emp/add")
public Result demo1(@Valid Emp emp,@NotBlank String email){
return Result.success(200,"成功");
}@Validated和@Valid的區(qū)別
@Validated:
Spring提供的支持分組校驗(yàn)可以用在類型、方法和方法參數(shù)上。但是不能用在成員屬性(字段)上由于無法加在成員屬性(字段)上,所以無法單獨(dú)完成級(jí)聯(lián)校驗(yàn),需要配合@Valid
@Valid:
JDK提供的(標(biāo)準(zhǔn)JSR-303規(guī)范)不支持分組校驗(yàn)可以用在方法、構(gòu)造函數(shù)、方法參數(shù)和成員屬性(字段)上可以加在成員屬性(字段)上,能夠獨(dú)自完成級(jí)聯(lián)校驗(yàn)
3. 級(jí)聯(lián)驗(yàn)證
一個(gè)待驗(yàn)證的pojo類,其中又包含了一個(gè)待驗(yàn)證的對(duì)象。
@Data
public class Emp implements Serializable {
//不能為空且不能為空串(調(diào)用trim()后)
@NotBlank(message = "賬號(hào)不能為空")
private String username;
@Valid //需要加上,否則不會(huì)驗(yàn)證Dept類中的校驗(yàn)注解
@NotNull //并且需要觸發(fā)該字段的驗(yàn)證才會(huì)進(jìn)行嵌套驗(yàn)證。
private Dept dept;
}
@Data
public class Dept implements Serializable {
@NotBlank(message = "deptNameb不能為空")
private String deptName;
}4. 分組驗(yàn)證
驗(yàn)證時(shí)只對(duì)特定的屬性進(jìn)行校驗(yàn),不知道默認(rèn)為Default
4.1定義接口,充當(dāng)標(biāo)識(shí)
public interface IGroup {
interface Registry extends Default {}
interface Update extends Default {}
}4.2 指定校驗(yàn)的組
@Data
public class Emp implements Serializable {
//當(dāng)校驗(yàn)的組為update時(shí)才校驗(yàn)該字段
@NotNull(message = "編號(hào)不能為空",groups = {IGroup.Update.class})
@Min(value = 1,groups = {IGroup.Update.class})
private Integer empNo;
//不能為空且不能為空串(調(diào)用trim()后)
@NotBlank(message = "賬號(hào)不能為空")
private String username;
@Pattern(regexp = "^[0-9A-z]{10,18}$",message = "密碼只能使用數(shù)字+字母",groups = IGroup.Registry.class)
private String password;
@Valid
@NotNull
private Dept dept;
}@PostMapping("/emp/add") //指定需要校驗(yàn)的組
public Result addEmp(@RequestBody @Validated(IGroup.Registry.class) Emp emp){
return Result.success(200,"成功");
}
5. 組序列
指定組與組之間的檢驗(yàn)順序,如果第一個(gè)組校驗(yàn)沒過,就不會(huì)校驗(yàn)后面的組
@GroupSequence({Default.class,IGroup.Update.class, IGroup.Registry.class})
public interface IGroup {
interface Registry extends Default {}
interface Update extends Default {}
}@PostMapping("/emp/add")
public Result addEmp(@RequestBody @Validated({IGroup.class}) Emp emp){
return Result.success(200,"成功");
}
隨便定義一個(gè)接口然后在接口上使用@GroupSequence就行。
還有一個(gè)注解是@GroupSequenceProvider,使用這個(gè)注解需要實(shí)現(xiàn)DefaultGroupSequenceProvider接口,重寫里面getValidationGroups方法,然后根據(jù)情況動(dòng)態(tài)的添加需要需要校驗(yàn)的分組。
6. 自定義校驗(yàn)注解
按照官網(wǎng)的示例
檢查當(dāng)前字符串是否為全大寫,或者全小寫
定義模型:
public interface CaseMode{
String UPPER="大寫";
String LOWER="小寫";
}創(chuàng)建自定義注解:
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = CheckCaseValidator.class) //指定自定義驗(yàn)證器
@Documented
@Repeatable(CheckCase.List.class) //表示可以在同一位置重復(fù)多次
public @interface CheckCase {
//默認(rèn)的錯(cuò)誤信息
String message() default "{verification.default.Errormessage}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
String value();
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@interface List {
CheckCase[] value();
}
}創(chuàng)建自定義驗(yàn)證器,第一個(gè)泛型是自定義注解、第二個(gè)是校驗(yàn)值的類型,也就是注解標(biāo)注的字段的類型
public class CheckCaseValidator implements ConstraintValidator<CheckCase, String> {
private String caseMode;
@Override
public void initialize(CheckCase constraintAnnotation) {
this.caseMode = constraintAnnotation.value();
}
/**
* 判斷是否通過校驗(yàn)
* @param value 傳入的值
* @param context
* @return
*/
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if ( value == null ) {
return true;
}
if (CaseMode.UPPER.equals(caseMode) ) {
return value.equals( value.toUpperCase() );
}
else {
return value.equals( value.toLowerCase() );
}
}
}在 resources 目錄下創(chuàng)建一個(gè) ValidationMessages.properties 配置文件,key 是第二步 message 設(shè)置的默認(rèn)值,value 是自定義錯(cuò)誤信息。{value}為 @CheckCase的value屬性的值
verification.default.Errormessage=字母必須為全為{value}
7. 校驗(yàn)結(jié)果的處理
7.1 全局異常處理
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BindException.class)
public HashMap<String, String> bindExceptionHandler(BindException e){
HashMap<String, String> map = new HashMap<>();
e.getBindingResult().getFieldErrors().forEach(field -> {
map.put(field.getField(), field.getDefaultMessage());
});
return map;
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public HashMap<String, String> methodArgumentNotValidException(MethodArgumentNotValidException e){
HashMap<String, String> map = new HashMap<>();
e.getBindingResult().getFieldErrors().forEach(field -> {
map.put(field.getField(), field.getDefaultMessage());
});
return map;
}
@ExceptionHandler(ConstraintViolationException.class)
public HashMap<String, String> handle(ConstraintViolationException e) {
HashMap<String, String> map = new HashMap<>();
e.getConstraintViolations().forEach(item->{
map.put(item.getPropertyPath().toString(),item.getMessage());
});
return map;
}
}
7.2 BindRequest
@PostMapping("/emp/test")
public Result test(@Validated Emp emp, BindingResult validResult){
if (validResult.hasErrors()){
HashMap<String, String> map = new HashMap<>();
validResult.getFieldErrors().forEach(error->{
map.put(error.getField(),error.getDefaultMessage());
});
return Result.error(HttpStatus.BAD_REQUEST.value(),map);
}
return Result.success(HttpStatus.OK.value(),"成功");
}7.3 Validator
@SpringBootTest
public class ValidatorTest {
private static Validator validator = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(false) // 是否開啟快速失敗模式
.buildValidatorFactory()
.getValidator();
@Test
public void test1(){
Emp emp = new Emp();
//單獨(dú)校驗(yàn)?zāi)硞€(gè)屬性
//Set<ConstraintViolation<Emp>> validProperty = validator.validateProperty(emp, "username");
//檢驗(yàn)對(duì)象
Set<ConstraintViolation<Emp>> validBean = validator.validate(emp);
Iterator<ConstraintViolation<Emp>> iterator = validBean.iterator();
while (iterator.hasNext()){
ConstraintViolation<Emp> next = iterator.next();
String property = next.getPropertyPath().toString();
String message = next.getMessage();
System.out.println(property+":"+message);
}
}
}到此這篇關(guān)于Java中JSR303的基本使用詳情的文章就介紹到這了,更多相關(guān)Java JSR303內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot使用AOP在指定方法執(zhí)行完后執(zhí)行異步處理操作
這篇文章主要介紹了Spring Boot使用AOP在指定方法執(zhí)行完后執(zhí)行異步處理操作,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06
Java8 CompletableFuture 異步執(zhí)行操作
CompletableFuture是java8提供的基于異步操作的封裝,日常開發(fā)中經(jīng)常會(huì)用到,接下來通過本文給大家介紹Java8 CompletableFuture 異步執(zhí)行操作,感興趣的朋友一起看看吧2021-06-06
使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級(jí)的代碼示例
Sentinel是面向分布式、多語言異構(gòu)化服務(wù)架構(gòu)的流量治理組件,本文將詳細(xì)為大家介紹如何使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級(jí),文中有相關(guān)的代碼示例,需要的朋友可以參考下2023-05-05
java中rss解析器(rome.jar和jdom.jar)示例
這篇文章主要介紹了java中rss解析器(rome.jar和jdom.jar)示例,需要的朋友可以參考下2014-03-03
淺談SpringMVC+Spring3+Hibernate4開發(fā)環(huán)境搭建
MVC已經(jīng)是現(xiàn)代Web開發(fā)中的一個(gè)很重要的部分,本文介紹一下SpringMVC+Spring3+Hibernate4的開發(fā)環(huán)境搭建,有興趣的可以了解一下。2017-01-01
Java實(shí)現(xiàn)OJ多組測(cè)試數(shù)據(jù)的輸入方法
今天小編就為大家分享一篇Java實(shí)現(xiàn)OJ多組測(cè)試數(shù)據(jù)的輸入方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07

