一、JSR 303 是什麼?
JSR-303 是 Java EE 6 中的一項子規範,叫做 Bean Validation,官方參考實現是hibernate Validator。
二、JSR 303 能做什麼?
- 1.JSR 303 用於對java Bean 中的字段的值進行驗證,使得基本的驗證邏輯可以從業務代碼中脫離出來。
- 2.是一個運行時的數據驗證框架,在驗證之後驗證的錯誤信息會被馬上返回。
三、都有些什麼驗證?
hibernate Validator對JSR303做了比較全面的實現,springboot 自帶,並且還額外提供了一些實現,如下:
Constraint | 說明 | 作用類型 |
---|---|---|
@Null | 被註釋的元素必須爲 null | 引用類型 |
@NotNull | 被註釋的元素必須不爲 null | 引用類型 |
@AssertTrue | 被註釋的元素必須爲 true | boolean |
@AssertFalse | 被註釋的元素必須爲 false | boolean |
@Min(value) | 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值 | byte、short、int、long及對應的包裝類型以及BigDecimal、BigInteger |
@Max(value) | 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值 | byte、short、int、long及對應的包裝類型以及BigDecimal、BigInteger |
@DecimalMin(value) | 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值 | byte、short、int、long及對應的包裝類型以及BigDecimal、BigInteger、String |
@DecimalMax(value) | 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值 | byte、short、int、long及對應的包裝類型以及BigDecimal、BigInteger、String |
@Size(max, min) | 被註釋的元素的大小必須在指定的範圍內 | String、Collection、Map和數組 |
@Digits (integer, fraction) | 被註釋的元素必須是一個數字,其值必須在可接受的範圍內 | byte、short、int、long及各自的包裝類型以及BigDecimal、BigInteger、String |
@Past | 被註釋的元素必須是一個過去的日期 | java.util.Date,java.util.Calendar |
@Future | 被註釋的元素必須是一個將來的日期 | java.util.Date,java.util.Calendar |
@Pattern(regex=) | 被註釋的元素必須符合指定的正則表達式 | String |
@Valid | 被註釋的元素需要遞歸驗證 | 引用對象 |
以下是hibernate Validator新增的
Constraint | 說明 | 作用類型 |
---|---|---|
被註釋的元素必須是電子郵箱地址 | String | |
@Length(min=下限, max=上限) | 被註釋的字符串的大小必須在指定的範圍內 | String |
@NotEmpty | 被註釋的元素的必須非空並且size大於0 | String、Collection、Map和數組 |
@NotBlank | 被註釋的元素必須不爲空且不能全部爲’ '(空字符串) | String |
@Range(min=最小值, max=最大值) | 被註釋的元素必須在合適的範圍內 | byte、short、int、long及各自的包裝類型以及BigDecimal、BigInteger、String |
注意:@Valid 和 BindingResult 是一一對應的,如果有多個@Valid,那麼每個@Valid後面跟着的BindingResult就是這個@Valid的驗證結果,順序不能亂
四、參考示例操作
方法上添加 @Validated
public Result<Void> insert(@RequestBody @Validated TradeSpuCategoryDto tradeSpuCategoryDto) {
傳遞參數的實體類中 ,如有嵌套驗證使用 @Valid
@NotNull(message = "不能爲空")
private String attrName;
@Min(value = 1, message = "不能小於1")
private Integer stockWarning;
@DecimalMin(value="0.00",message = "必須大於等於0")
private BigDecimal commission;
// 嵌套驗證
@Valid
private List<SkuVerifyDto> skuVerifyDto;
五、@Validated和 @Valid 的區別
- @Validated:可以用在類型、方法和方法參數上。但是不能用在成員屬性(字段)上
- @Valid:可以用在方法、構造函數、方法參數和成員屬性(字段)上
兩者是否能用於成員屬性(字段)上直接影響能否提供嵌套驗證的功能。
六、需要的依賴(springboot 自帶,無需添加)
<!--jsr 303-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.1.0.Final</version>
</dependency>
<!-- hibernate validator-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.0.Final</version>
</dependency>
七、參數異常返回前端 (注意此異常爲受檢查異常)
會檢查前端傳遞的參數返回對應的錯誤信息
/**
* 異常處理類/ 全局異常 /自定義異常
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler extends BaseService {
/**
* TODO 全局異常 --> 受檢查異常。可以理解爲錯誤,必須要開發者解決以後才能編譯通過,這裏JSR 303 爲受檢查異常
* 解決的方法有兩種1:throw到上層,2,try-catch處理。
*
* @param e
* @author ws
* @mail [email protected]
* @date 2020/2/9 0009 10:06
*/
@ExceptionHandler(Exception.class)
public Result<String> exceptionHandler(Exception e) {
StringBuffer url = request.getRequestURL();
log.info("###全局受檢查異常###,url:{} --> ERROR:{}", url, e.getMessage());
if (e instanceof MethodArgumentNotValidException) {
// JSR 303 爲參數驗證錯誤
return new Result<String>(ResultType.SYSTEM_VALID_ILLEGAL_PARAM, e.getMessage());
} else if (e instanceof MissingServletRequestParameterException) {
// 未傳遞Parameter 參數驗證錯誤,一般方法測試指定了 @Parameter 的參數未傳遞
return new Result<String>(ResultType.SYSTEM_PARAMETER_ILLEGAL_PARAM, e.getMessage());
}
// Result 爲返回數據對象,
// ResultType.SYSTEM_ERROR=返回的code和msg,
// e.getMessage() =當前錯誤信息
return new Result<String>(ResultType.SYSTEM_ERROR, e.getMessage());
}
}