一:簡介
1. JSR-303 是 JAVA EE 6 中的一項子規範,叫做 Bean Validation。
2. 在任何時候,當你要處理一個應用程序的業務邏輯,數據校驗是你必須要考慮和麪對的事情。
3. Bean Validation 爲 JavaBean 驗證定義了相應的元數據模型和 API。
4. constraint 可以附加到字段,getter 方法,類或者接口上面。
5. 對於一些特定的需求,用戶可以很容易的開發定製化的 constraint。
6. Bean Validation 是一個運行時的數據驗證框架,在驗證之後驗證的錯誤信息會被馬上返回。
二:Bean Validation 規範內嵌的約束註解
限制 | 說明 |
---|---|
@Null | 限制只能爲null |
@NotNull | 限制必須不爲null |
@AssertFalse | 限制必須爲false |
@AssertTrue | 限制必須爲true |
@DecimalMax(value) | 限制必須爲一個不大於指定值的數字 |
@DecimalMin(value) | 限制必須爲一個不小於指定值的數字 |
@Digits(integer,fraction) | 限制必須爲一個小數,且整數部分的位數不能超過integer,小數部分的位數不能超過fraction |
@Future | 限制必須是一個將來的日期 |
@Max(value) | 限制必須爲一個不大於指定值的數字 |
@Min(value) | 限制必須爲一個不小於指定值的數字 |
@Past | 限制必須是一個過去的日期 |
@Pattern(value) | 限制必須符合指定的正則表達式 |
@Size(max,min) | 限制字符長度必須在min到max之間 |
@Past | 驗證註解的元素值(日期類型)比當前時間早 |
@NotEmpty | 驗證註解的元素值不爲null且不爲空(字符串長度不爲0、集合大小不爲0) |
@NotBlank | 驗證註解的元素值不爲空(不爲null、去除首位空格後長度爲0),不同於@NotEmpty,@NotBlank只應用於字符串且在比較時會去除字符串的空格 |
驗證註解的元素值是Email,也可以通過正則表達式和flag指定自定義的email格式 |
三:基本應用
1、引入依賴
<!--引入validation的場景啓動器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2、給參數對象添加校驗註解
private Integer id;
@NotBlank(message = "名稱不能爲空")
private String name;
private Date data;
@NotNull(message = "年齡不能爲空")
private Integer age;
@Pattern(regexp = "[0-9]" , message = "參數格式錯誤")
private String Telephone;
Controller 中需要校驗的參數Bean前添加 @Validated開啓校驗功能,緊跟在校驗的Bean後添加一個BindingResult,BindingResult封裝了前面Bean的校驗結果。
@GetMapping("/into")
public String into(@Validated Emp emp ,BindingResult bindingResult) {
if(bindingResult.hasErrors()){
Map<String,String> map = new HashMap<>();
bindingResult.getFieldErrors().forEach((item) ->{
String msg = item.getDefaultMessage();
String fie = item.getField();
map.put(fie,msg);
});
return map.toString();
}
return "200";
}
四:異常的統一處理
參數校驗不通過時,會拋出 BingBindException 異常,可以在統一異常處理中,做統一處理,這樣就不用在每個需要參數校驗的地方都用 BindingResult 獲取校驗結果了。
/**
* 自定義驗證異常(參數傳值)
*/
@ExceptionHandler(BindException.class)
public String validatedBindException(BindException e) {
String message = e.getAllErrors().get(0).getDefaultMessage();
return message;
}
/**
* 自定義驗證異常(json傳值)
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public String MethodArgumentNotValidException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
return message;
}
五:分組解決校驗
新增和修改對於實體的校驗規則是不同的,例如id是自增的時,新增時id要爲空,修改則必須不爲空;新增和修改,若用的恰好又是同一種實體,那就需要用到分組校驗;
校驗註解都有一個groups屬性,可以將校驗註解分組,我們看下@NotNull的源碼
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(NotNull.List.class)
@Documented
@Constraint( validatedBy = {} )
public @interface NotNull {
String message() default "{javax.validation.constraints.NotNull.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
NotNull[] value();
}
}
從源碼可以看出 groups 是一個Class<?>類型的數組,那麼就可以創建一個Groups.
public class Groups {
public interface Add {
}
public interface Update {
}
}
給參數對象的校驗註解添加分組
private Integer id;
@NotBlank(message = "名稱不能爲空" ,groups = Groups.Add.class)
private String name;
private Date data;
@NotNull(message = "年齡不能爲空",groups = {Groups.Add.class,Groups.Update.class})
private Integer age;
@Pattern(regexp = "[0-9]" , message = "電話格式錯誤")
private String Telephone;
在Controller 添加分組;多個可用@Validated({Groups.Update.class,Groups.Add.class})
@GetMapping("/into")
public String into(@Validated({Groups.Update.class}) Emp emp ) {
return "200";
}
六:配置文件配置massage錯誤信息
在resource 目錄下新建提示信息配置文件“ValidationMessages.properties“
注意:名字必須爲“ValidationMessages.properties“ 因爲SpringBoot自動讀取classpath中的ValidationMessages.properties裏的錯誤信息
@NotBlank(message = "{emp.name}" ,groups = Groups.Add.class)
private String name;
emp.name=參數錯誤