日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JSR303注解字段校验

發布時間:2024/3/13 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JSR303注解字段校验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JSR303是一套JavaBean參數校驗的標準,定義了很多常用的校驗注解
可以直接將這些注解加在我們JavaBean的屬性上面就可以在需要校驗的時候進行校驗了

依賴

<!-- 屬性效驗--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency>

一、JSR303定義的校驗類型

空檢查
@Null傳參不包括該字段,或者傳參該字段值為null
@NotNull 字段必傳,且字段值不能為null,String可為空字符串,Interger不能為空字符串(表單值為 “” 時,可以轉換:Stirng為"",Integer為Null),一般加在Interger類型上
@NotBlank字段必傳,且字段值不能為null,去掉前后空格長度大于0(trim()),一般加在字符串上
@NotEmpty字段必傳,且字段值不能為null,加在字符串上效果同@NotBlank,也可以加在(Array,Collection,Map)上,判斷不能null,一般加在集合、列表、Map上
Booelan檢查
@AssertTrueBoolean 成員變量的值只能為 true
@AssertFalseBoolean 成員變量的值只能為 false
長度檢查
@Size(min=, max=)校驗對象(Array,Collection,Map,String)長度是否在給定的范圍之內,一般加在列表、集合、Map上
@Length(min=, max=)校驗字符串長度是否在指定范圍內,只能加在字符串上
日期檢查
@Past驗證 Date 和 Calendar 對象是否在當前時間之前
@Future驗證 Date 和 Calendar 對象是否在當前時間之后
@Pattern驗證 String 對象是否符合正則表達式的規則
數值檢查建議使用在Stirng,Integer類型,不建議使用在int類型上,因為表單值為“”時無法轉換為int,但可以轉換為Stirng為"",Integer為null
@MinNumber 和 String 對象值大于等于指定的值
@MaxNumber 和 String 對象值小于等于指定的值
@DecimalMax被標注的值必須不大于約束中指定的最大值. 這個約束的參數是一個通過BigDecimal定義的最大值的字符串表示.小數存在精度
@DecimalMin被標注的值必須不小于約束中指定的最小值. 這個約束的參數是一個通過BigDecimal定義的最小值的字符串表示.小數存在精度
@Digits驗證 Number 和 String 的構成是否合法
@Digits(integer=,fraction=)驗證字符串是否是符合指定格式的數字,interger指定整數精度,fraction指定小數精度。
@Range(min=, max=)檢查數字是否介于min和max之間.
@Range(min=10000,max=50000,message=“range.bean.wage”)private BigDecimal wage;
@Valid遞歸的對關聯對象進行校驗, 如果關聯對象是個集合或者數組,那么對其中的元素進行遞歸校驗,如果是一個map,則對其中的值部分進行校驗.(是否進行遞歸驗證)
@CreditCardNumber信用卡驗證
@Email驗證是否是郵件地址,如果為null,不進行驗證,算通過驗證。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)

場景一:前端傳過來的字段如何在后臺做效驗,最老的方法就是if else顯得不是很靈活。如果前端傳來100個字段就得寫許多多余的代碼。
第一個場景就是在后臺創建的實體和前端傳來的字段做對應映射,加上JSR303注解來做靈活的效驗

1:給Bean實體添加校驗注解:javax.validation.constraints(大部分注解都在這個包下),并定義自己的message提示如下:

二、在Springboot項目中使用

2.1、編寫需要校驗的Bean

package com.example.jsr.entity;import com.example.jsr.Constant; import lombok.Data; import org.hibernate.validator.constraints.Length;import javax.validation.constraints.*; import java.io.Serializable; import java.util.List;/*** @author Deyou Kong* @description 品牌實體類* @date 2023/2/25 9:16 上午*/@Data public class Brand implements Serializable {/*** ID*/private Integer id;/*** 品牌名稱*/@NotBlank(message = Constant.NAME_NOT_NULL)@Length(min = 2, max = 32, message = "品牌長度為2-32")private String name;/*** 描述*/@NotNull(message = "描述不能為空NotNull")private String description;/*** 排序*/@Min(value = 1, message = "不能小于1")@Max(value = 10, message = "不能大于10")@NotNull(message = "排序不能為空")private Integer sort;@NotEmpty(message = "關聯應用不能為空")@Size(min = 1, message = "品牌最少關聯一個應用")private List<Integer> appList;}

2.2、Controller方法中增加校驗注解

@RestController @RequestMapping("/brand") public class BrandController {@Resourceprivate BrandService brandService;@PostMapping("/save")public JsonResult saveBrand(@Validated @RequestBody Brand brand, BindingResult bindingResult) {System.out.println("進入controller的save方法");if (bindingResult.hasErrors()) {//1.出現參數非法情況Map<String, String> map = new HashMap<>();bindingResult.getFieldErrors().forEach(fieldError -> {map.put(fieldError.getField(), fieldError.getDefaultMessage());});JsonResult jsonResult = JsonResult.fail("參數不正確,請檢查");jsonResult.setData(map);return jsonResult;} else {//2.參數驗證通過, 執行正常邏輯brandService.saveBrand(brand);return JsonResult.commonSuccess();}} }

備注:這里一個@Validated (org.springframework.validation.annotation.Validated;)的參數后必須緊挨著一個BindingResult 參數接收參數效驗的結果,否則spring會在校驗不通過時直接拋出異常

2.3、統一異常處理

添加BindingResult參數后,雖然可以使后臺在出現異常時,進行處理并返回統一的結果。但是我們會發現,我們寫了許多與業務不相關的代碼,為了解決這個問題,我們可以通過@ControllerAdvice進行異常的統一處理。

1、編寫統一異常處理類

package com.example.jsr.advice;import com.example.jsr.entity.JsonResult; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.BindingResult; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap; import java.util.Map;/*** @author Deyou Kong* @description 全局異常捕獲處理器* @date 2023/2/25 10:57 下午*/@RestControllerAdvice @Slf4j public class GlobalExceptionControllerAdvice {/*** 出現參數非法情況,拋出MethodArgumentNotValidException異常,在此捕獲處理* @param e* @return*/@ExceptionHandler(MethodArgumentNotValidException.class)public JsonResult handlerMethodArgumentNotValidException(MethodArgumentNotValidException e){BindingResult bindingResult = e.getBindingResult();Map<String, String> map = new HashMap<>();bindingResult.getFieldErrors().forEach(fieldError -> {map.put(fieldError.getField(), fieldError.getDefaultMessage());});JsonResult jsonResult = JsonResult.fail("參數不正確,請檢查");jsonResult.setData(map);return jsonResult;}/**兜底* @param e* @return*/@ExceptionHandler(Exception.class)public JsonResult handlerException(Exception e){JsonResult jsonResult = JsonResult.fail("未知的系統異常");jsonResult.setData(e.getMessage());return jsonResult;} }

2、把之前加的BindingResult去掉,還原成原先最干凈的代碼

@RestController @RequestMapping("/brand") public class BrandController {@Resourceprivate BrandService brandService;@PostMapping("/save")public JsonResult saveBrand(@Validated @RequestBody Brand brand) {System.out.println("進入controller的save方法");brandService.saveBrand(brand);return JsonResult.commonSuccess();} }

三、分組效驗

在簡單的數據驗證中,我們使用完成了數據驗證。但是還存在一些問題,如在添加品牌的時候Id為null,但在修改品牌的時候Id不能為null,這樣的話,就沖突了。

那怎么辦呢?我們可以給他們分個組,添加操作使用一組驗證規則,修改操作使用一組驗證規則。這就是分組驗證的功能。

以@NotNull注解為例

@Constraint(validatedBy = { }) public @interface NotNull {String message() default "{javax.validation.constraints.NotNull.message}";//分組驗證時使用Class<?>[] groups() default { };...

我們通過@NotNul注解的groups指定屬于哪個組

實現步驟:

1、創建AddGroup和UpdateGroup接口分別表示添加組和更新組

//這倆個接口只是用來標記的,不需要實現 public interface AddGroup { }public interface UpdateGroup { }

2、實體類中使用注解時,標明該驗證規則屬于哪個組

@Data public class Brand implements Serializable {/*** ID*/@NotNull(message = "ID不能為空", groups = {UpdateGroup.class})private Integer id;/*** 品牌名稱*/@NotBlank(message = Constant.NAME_NOT_NULL, groups = {AddGroup.class, UpdateGroup.class})@Length(min = 2, max = 32, message = "品牌長度為2-32", groups = {AddGroup.class, UpdateGroup.class})private String name;/*** 描述*/@NotNull(message = "描述不能為空NotNull")private String description;/*** 排序*/@Min(value = 1, message = "不能小于1")@Max(value = 10, message = "不能大于10")@NotNull(message = "排序不能為空")private Integer sort;@NotEmpty(message = "關聯應用不能為空")@Size(min = 1, message = "品牌最少關聯一個應用")private List<Integer> appList; }

3、Controller中嬌艷注解必須為@Validated

注意:
使用分組功能時,必須使用 @Validated 替代 @Valid,它支持分組效驗功能

@PostMapping("/save") public JsonResult saveBrand(@Validated(AddGroup.class) @RequestBody Brand brand) {System.out.println("進入controller的save方法");brandService.saveBrand(brand);return JsonResult.commonSuccess(); }@PostMapping("/update") public JsonResult updateBrand(@Validated(UpdateGroup.class) @RequestBody Brand brand){System.out.println("進入controller的update方法");brandService.updateBrand(brand);return JsonResult.success(""); }

4、測試

1、上面實體類中 name 字段的@NotBlank、@Length兩個注解對AddGroup、UpdateGroup兩個分組都生效,所以測試結果中都有錯誤提示
2、ID字段只針對UpdateGroup分組生效,測試結果顯示只針對update接口進行判斷
3、其他字段的注解均未指定分組,那么在Controller指定分組的情況下,這些字段上面的校驗注解不生效

四、自定義效驗注解

步驟:
1、編寫一個自定義的效驗注解
2、編寫一個自定義的效驗器
3、關聯自定義的效驗器和自定義的效驗注解

1、Brand實體類中增加一個字段

private String logo; // 需要判斷logo地址是否以http開頭

2、、自定義 IsUrl 注解類

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) @Documented @Constraint(validatedBy = {IsUrlValidator.class }) public @interface IsUrl {//JSR303規范中,要求必須有message、groups、payload這三個方法//default: 當message為null時,默認會到ValidationMessages.properties配置文件中找com.fcp.common.valid.ListValue.message的值String message() default "{com.fcp.common.valid.ListValue.message}";Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };// 注解中用戶配置的字段值,如我指定url的規則存放哪個字段,這里存放在value字段中String value() default ""; }

3、編寫一個自定義的效驗器IsUrlValidator.class
校驗器的類名與注解類中Constraint中類名一致

//IsUrl:自定義的注解 //String:注解參數類型 public class IsUrlValidator implements ConstraintValidator<IsUrl, String> {/*** 接收我們自定義的屬性value,默認為""*/private String value = "";/*** 1、初始化方法:通過該方法我們可以拿到我們的注解* @param constraintAnnotation*/@Overridepublic void initialize(IsUrl constraintAnnotation) {// 接收我們自定義的屬性value,默認為""value = constraintAnnotation.value();}/*** //2、邏輯處理* @param s 前端傳參的值* @param constraintValidatorContext* @return*/@Overridepublic boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {System.out.println("注解獲取到的值為:" + value);System.out.println("用戶傳參:"+ s);boolean b = s.startsWith(value);System.out.println(b);return b;} }

4、在實體類中使用注解

@IsUrl(value = "https:", message = "URL地址不正確", groups = {AddGroup.class, UpdateGroup.class})@NotBlank(message = "logo不能為空")private String logo;

5、測試

五、校驗順序

在測試過程中,發現多個注解校驗順序不定,這里還不知道怎么解決
看到一篇文章https://blog.csdn.net/qq_41762594/article/details/109326971,等后面有空在研究

總結

以上是生活随笔為你收集整理的JSR303注解字段校验的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。