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

歡迎訪問 生活随笔!

生活随笔

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

javascript

springboot获取payload_Spring Boot 使用 JSR303 实现参数验证

發布時間:2025/3/19 javascript 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot获取payload_Spring Boot 使用 JSR303 实现参数验证 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章首發于公眾號《程序員果果》 地址 : http://blog.itwolfed.com/blog/97

簡介

JSR-303 是 JAVA EE 6 中的一項子規范,叫做 Bean Validation。

在任何時候,當你要處理一個應用程序的業務邏輯,數據校驗是你必須要考慮和面對的事情。應用程序必須通過某種手段來確保輸入進來的數據從語義上來講是正確的。在通常的情況下,應用程序是分層的,不同的層由不同的開發人員來完成。很多時候同樣的數據驗證邏輯會出現在不同的層,這樣就會導致代碼冗余和一些管理的問題,比如說語義的一致性等。為了避免這樣的情況發生,最好是將驗證邏輯與相應的域模型進行綁定。

Bean Validation 為 JavaBean 驗證定義了相應的元數據模型和 API。缺省的元數據是 Java Annotations,通過使用 XML 可以對原有的元數據信息進行覆蓋和擴展。在應用程序中,通過使用 Bean Validation 或是你自己定義的 constraint,例如 @NotNull, @Max, @ZipCode, 就可以確保數據模型(JavaBean)的正確性。constraint 可以附加到字段,getter 方法,類或者接口上面。對于一些特定的需求,用戶可以很容易的開發定制化的 constraint。Bean Validation 是一個運行時的數據驗證框架,在驗證之后驗證的錯誤信息會被馬上返回。

Bean Validation 規范內嵌的約束注解

實例

基本應用

引入依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency>

給參數對象添加校驗注解

@Data public class User {private Integer id;@NotBlank(message = "用戶名不能為空")private String username;@Pattern(regexp = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$", message = "密碼必須為8~16個字母和數字組合")private String password;@Emailprivate String email;private Integer gender;}

Controller 中需要校驗的參數Bean前添加 @Valid 開啟校驗功能,緊跟在校驗的Bean后添加一個BindingResult,BindingResult封裝了前面Bean的校驗結果。

@RestController @RequestMapping("/user") public class UserController {@PostMapping("")public Result save (@Valid User user , BindingResult bindingResult) {if (bindingResult.hasErrors()) {Map<String , String> map = new HashMap<>();bindingResult.getFieldErrors().forEach( (item) -> {String message = item.getDefaultMessage();String field = item.getField();map.put( field , message );} );return Result.build( 400 , "非法參數 !" , map);}return Result.ok();}}

測試如下:

異常的統一處理

參數校驗不通過時,會拋出 BingBindException 異常,可以在統一異常處理中,做統一處理,這樣就不用在每個需要參數校驗的地方都用 BindingResult 獲取校驗結果了。

@Slf4j @RestControllerAdvice(basePackages = "com.itwolfed.controller") public class GlobalExceptionControllerAdvice {@ExceptionHandler(value= {MethodArgumentNotValidException.class , BindException.class})public Result handleVaildException(Exception e){BindingResult bindingResult = null;if (e instanceof MethodArgumentNotValidException) {bindingResult = ((MethodArgumentNotValidException)e).getBindingResult();} else if (e instanceof BindException) {bindingResult = ((BindException)e).getBindingResult();}Map<String,String> errorMap = new HashMap<>(16);bindingResult.getFieldErrors().forEach((fieldError)->errorMap.put(fieldError.getField(),fieldError.getDefaultMessage()));return Result.build(400 , "非法參數 !" , errorMap);}}

分組解決校驗

新增和修改對于實體的校驗規則是不同的,例如id是自增的時,新增時id要為空,修改則必須不為空;新增和修改,若用的恰好又是同一種實體,那就需要用到分組校驗。

校驗注解都有一個groups屬性,可以將校驗注解分組,我們看下@NotNull的源碼:

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Repeatable(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({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)@Documented@interface List {NotNull[] value();} }

從源碼可以看出 groups 是一個Class<?>類型的數組,那么就可以創建一個Groups.

public class Groups {public interface Add{}public interface Update{} }

給參數對象的校驗注解添加分組

@Data public class User {@Null(message = "新增不需要指定id" , groups = Groups.Add.class)@NotNull(message = "修改需要指定id" , groups = Groups.Update.class)private Integer id;@NotBlank(message = "用戶名不能為空")@NotNullprivate String username;@Pattern(regexp = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$", message = "密碼必須為8~16個字母和數字組合")private String password;@Emailprivate String email;private Integer gender;}

Controller 中原先的@Valid不能指定分組 ,需要替換成@Validated

@RestController @RequestMapping("/user") public class UserController {@PostMapping("")public Result save (@Validated(Groups.Add.class) User user) {return Result.ok();}}

測試如下:

自定義校驗注解

雖然JSR303和springboot-validator 已經提供了很多校驗注解,但是當面對復雜參數校驗時,還是不能滿足我們的要求,這時候我們就需要 自定義校驗注解。

例如User中的gender,用 1代表男 2代表女,我們自定義一個校驗注解@ListValue,指定取值只能1和2。

創建約束規則

@Documented @Constraint(validatedBy = { ListValueConstraintValidator.class }) @Target({ METHOD, FIELD, ANNOTATION_TYPE }) @Retention(RUNTIME) public @interface ListValue {String message() default "";Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };int[] vals() default { }; }

一個標注(annotation) 是通過@interface關鍵字來定義的. 這個標注中的屬性是聲明成類似方法 的樣式的. 根據Bean Validation API 規范的要求:

  • message屬性, 這個屬性被用來定義默認得消息模版, 當這個約束條件被驗證失敗的時候,通過 此屬性來輸出錯誤信息。
  • groups 屬性, 用于指定這個約束條件屬于哪(些)個校驗組. 這個的默認值必須是Class<?>類型數組。
  • payload 屬性, Bean Validation API 的使用者可以通過此屬性來給約束條件指定嚴重級別. 這個屬性并不被API自身所使用。

除了這三個強制性要求的屬性(message, groups 和 payload) 之外, 我們還添 加了一個屬性用來指定所要求的值. 此屬性的名稱vals在annotation的定義中比較特 殊, 如果只有這個屬性被賦值了的話, 那么, 在使用此annotation到時候可以忽略此屬性名稱.

另外, 我們還給這個annotation標注了一些元標注( meta annotatioins):

  • @Target({ METHOD, FIELD, ANNOTATION_TYPE }): 表示此注解可以被用在方法, 字段或者 annotation聲明上。
  • @Retention(RUNTIME): 表示這個標注信息是在運行期通過反射被讀取的.
  • @Constraint(validatedBy = ListValueConstraintValidator.class): 指明使用哪個校驗器(類) 去校驗使用了此標注的元素.
  • @Documented: 表示在對使用了該注解的類進行javadoc操作到時候, 這個標注會被添加到 javadoc當中.

創建約束校驗器

import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.HashSet; import java.util.Set;public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {private Set<Integer> set = new HashSet<>();/*** 初始化方法*/@Overridepublic void initialize(ListValue constraintAnnotation) {int[] vals = constraintAnnotation.vals();for (int val : vals) {set.add(val);}}/*** 判斷是否校驗成功** @param value 需要校驗的值* @param context* @return*/@Overridepublic boolean isValid(Integer value, ConstraintValidatorContext context) {return set.contains(value);} }

ListValueConstraintValidator定義了兩個泛型參數, 第一個是這個校驗器所服務到標注類型(在我們的例子中即ListValue), 第二個這個校驗器所支持到被校驗元素的類型 (即Integer)。

如果一個約束標注支持多種類型的被校驗元素的話, 那么需要為每個所支持的類型定義一個ConstraintValidator,并且注冊到約束標注中。

這個驗證器的實現就很平常了, initialize() 方法傳進來一個所要驗證的標注類型的實例, 在本 例中, 我們通過此實例來獲取其vals屬性的值,并將其保存為Set集合中供下一步使 用。

isValid()是實現真正的校驗邏輯的地方, 判斷一個給定的int對于@ListValue這個約束條件來說 是否是合法的。

在參數對象中使用@ListValue注解。

@Data public class User {@Null(message = "新增不需要指定id" , groups = Groups.Add.class)@NotNull(message = "修改需要指定id" , groups = Groups.Update.class)private Integer id;@NotBlank(message = "用戶名不能為空")@NotNullprivate String username;@Pattern(regexp = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$", message = "密碼必須為8~16個字母和數字組合")private String password;@Emailprivate String email;@ListValue( message = "性別應指定相應的值" , vals = {1,2} , groups = {Groups.Add.class , Groups.Update.class})private Integer gender;}

測試如下:

源碼地址

https://github.com/gf-huanchupk/SpringBootLearning

參考

https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/index.html https://docs.jboss.org/hibernate/validator/4.3/reference/zh-CN/pdf/hibernate_validator_reference.pdf

總結

以上是生活随笔為你收集整理的springboot获取payload_Spring Boot 使用 JSR303 实现参数验证的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 一级大黄毛片 | 国产在线精品二区 | 久久黄视频 | 亚洲成人tv | 最新av在线播放 | 不卡视频一区二区 | 综合网在线视频 | 三上悠亚在线一区 | 污视频导航| 欧美三级韩国三级日本三斤在线观看 | 97超碰人人爱 | 国产人妻777人伦精品hd | 蜜臀av性久久久久蜜臀aⅴ麻豆 | 国产免费专区 | 日本三级韩国三级三级a级按摩 | 99精品中文字幕 | 肉色超薄丝袜脚交一区二区 | 婷婷影院在线观看 | 久久人人澡 | 日本三级一区二区 | 好色先生tv官网 | 精品人妻无码一区二区三区蜜桃一 | 中文字幕无线精品亚洲乱码一区 | 特黄特色大片免费视频大全 | 精品人妻无码一区二区三 | av网站黄色| 国产成人一区二区三区别 | 天堂素人 | 日韩激情一区二区三区 | 中文字幕+乱码+中文 | 午夜影院在线看 | 久久久久久久久久久av | 日老女人视频 | 极品销魂美女少妇尤物 | 韩国一区视频 | 亚洲一区二区在线免费观看 | 色片网站在线观看 | 国产免费黄色小视频 | 懂色av一区二区三区免费 | 青青草激情 | 亚洲高清一区二区三区 | 久久久久中文字幕亚洲精品 | 久久aaaa片一区二区 | 精品日本一区二区三区 | 精品婷婷色一区二区三区蜜桃 | 伊人22综合 | 久久久久人妻一道无码AV | 国产乱子一区二区 | 欧美人妻少妇一区二区三区 | 天天干天天要 | 天天干免费视频 | 国产成人精品在线 | 久久大片 | 99精品热视频 | 综合久久激情 | 亚洲黄色片 | 少妇人妻无码专区视频 | 亚洲欧美经典 | 怒海潜沙秦岭神树 | 91香蕉国产 | 精品人妻午夜一区二区三区四区 | 国产精品xxx在线 | 国产一区二区免费在线观看 | 处女朱莉 | 影音先锋每日资源 | 国产精品无码白浆高潮 | 影音先锋中文字幕在线 | 国产成人一区二区三区别 | 亚洲中文字幕无码不卡电影 | 亚洲激情久久久 | 狠狠操一区 | 美女看片 | 色综合久久久久综合体桃花网 | 日本人妻丰满熟妇久久久久久 | 国产最新视频 | 欧美丰满熟妇bbb久久久 | 久久久久国产精品无码免费看 | 91大神在线观看视频 | 五月婷婷六月天 | 国内av片 | 国产又黄又大又粗的视频 | 国产精品成人在线观看 | 日韩一级片免费在线观看 | 亚洲福利av | 狠狠撸狠狠操 | 久久久精品人妻av一区二区三区 | 亚洲婷婷久久综合 | 亚洲一级精品 | 亚洲xxx视频 | 亚洲成人va | 日韩日b视频 | 熟女少妇一区二区三区 | 色妞网| 自偷自拍亚洲 | 果冻av在线 | 一道本一区| 91看黄| 激情导航| 强行挺进皇后紧窄湿润小说 |