成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring Boot 參數校驗以及分組校驗的使用

開發(fā) 后端
Bean Validation是Java定義的一套基于注解的數據校驗規(guī)范,目前已經從JSR 303的1.0版本升級到JSR 349的1.1版本,再到JSR 380的2.0版本(2.0完成于2017.08),已經經歷了三個版本 。本文基于validator的介紹資料,也結合自己在項目中的實際使用經驗進行了總結,希望能幫到大家。

 [[417101]]

一 前言

做web開發(fā)有一點很煩人就是要對前端輸入參數進行校驗,基本上每個接口都要對參數進行校驗,比如一些非空校驗、格式校驗等。如果參數比較少的話還是容易處理的一但參數比較多了的話代碼中就會出現大量的if-else語句。

使用這種方式雖然簡單直接,但是也有不好的地方,一是降低了開發(fā)效率,因為我們需要校驗的參數會存在很多地方,并且不同地方會有重復校驗,其次降低了代碼可讀性,因為在業(yè)務代碼中摻雜了太多額外工作的代碼。

所以我們可以使用validator組件來代替我們進行不必要的coding操作。本文基于validator的介紹資料,也結合自己在項目中的實際使用經驗進行了總結,希望能幫到大家。

1 什么是validator

Bean Validation是Java定義的一套基于注解的數據校驗規(guī)范,目前已經從JSR 303的1.0版本升級到JSR 349的1.1版本,再到JSR 380的2.0版本(2.0完成于2017.08),已經經歷了三個版本 。需要注意的是,JSR只是一項標準,它規(guī)定了一些校驗注解的規(guī)范,但沒有實現,比如@Null、@NotNull、@Pattern等,它們位于 javax.validation.constraints這個包下。而hibernate validator是對這個規(guī)范的實現,并增加了一些其他校驗注解,如 @NotBlank、@NotEmpty、@Length等,它們位于org.hibernate.validator.constraints這個包下。

如果我們的項目使用了Spring Boot,hibernate validator框架已經集成在 spring-boot-starter-web中,所以無需再添加其他依賴。如果不是Spring Boot項目,需要添加如下依賴。

二 注解介紹

1 validator內置注解

hibernate validator中擴展定義了如下注解:

三 使用

使用起來比較簡單,都是使用注解方式使用。具體來說分為單參數校驗、對象參數校驗,單參數校驗就是controller接口按照單參數接收前端傳值,沒有封裝對象進行接收,如果有封裝對象那就是對象參數校驗。

1 單參數校驗

單參數校驗只需要在參數前添加注解即可,如下所示:

  1. public Result deleteUser(@NotNull(message = "id不能為空") Long id) {  // do something} 

但有一點需要注意,如果使用單參數校驗,controller類上必須添加@Validated注解,如下所示:

  1. @RestController@RequestMapping("/user")@Validated // 單參數校驗需要加的注解public class UserController {  // do something} 

2 對象參數校驗

對象參數校驗使用時,需要先在對象的校驗屬性上添加注解,然后在Controller方法的對象參數前添加@Validated 注解,如下所示:

  1. public Result addUser(@Validated UserAO userAo) {    // do something}public class UserAO {  @NotBlank  private String name;  @NotNull  private Integer age;    ……} 

注解分組

在對象參數校驗場景下,有一種特殊場景,同一個參數對象在不同的場景下有不同的校驗規(guī)則。比如,在創(chuàng)建對象時不需要傳入id字段(id字段是主鍵,由系統(tǒng)生成,不由用戶指定),但是在修改對象時就必須要傳入id字段。在這樣的場景下就需要對注解進行分組。

1)組件有個默認分組Default.class, 所以我們可以再創(chuàng)建一個分組UpdateAction.class,如下所示:

public interface UpdateAction {}
2)在參數類中需要校驗的屬性上,在注解中添加groups屬性:

  1. public class UserAO {    @NotNull(groups = UpdateAction.class, message = "id不能為空")    private Long id;        @NotBlank    private String name;    @NotNull    private Integer age;        ……} 

如上所示,就表示只在UpdateAction分組下校驗id字段,在默認情況下就會校驗name字段和age字段。

然后在controller的方法中,在@Validated注解里指定哪種場景即可,沒有指定就代表采用Default.class,采用其他分組就需要顯示指定。如下代碼便表示在addUser()接口中按照默認情況進行參數校驗,在updateUser()接口中按照默認情況和UpdateAction分組對參數進行共同校驗。

  1. public Result addUser(@Validated UserAO userAo) {  // do something} 
  2. public Result updateUser(@Validated({Default.class, UpdateAction.class}) UserAO userAo) {  // do something} 

對象嵌套

如果需要校驗的參數對象中還嵌套有一個對象屬性,而該嵌套的對象屬性也需要校驗,那么就需要在該對象屬性上增加@Valid注解。

  1. public class UserAO {    @NotNull(groups = UpdateAction.class, message = "id不能為空")    private Long id;        @NotBlank    private String name;    @NotNull    private Integer age;        @Valid    private Phone phone;        ……}public class Phone {    @NotBlank    private String operatorType;        @NotBlank    private String phoneNum;} 

3 錯誤消息的捕獲

參數校驗失敗后會拋出異常,我們只需要在全局異常處理類中捕獲參數校驗的失敗異常,然后將錯誤消息添加到返回值中即可。捕獲異常的方法如下所示,返回值Result是我們系統(tǒng)自定義的返回值類。

  1. @RestControllerAdvice(basePackages= {"com.alibaba.dc.controller","com.alibaba.dc.service"})public class GlobalExceptionHandler {  @ExceptionHandler(value = {Throwable.class})  Result handleException(Throwable e, HttpServletRequest request){    // 異常處理        }} 

需要注意的是,如果缺少參數拋出的異常是MissingServletRequestParameterException,單參數校驗失敗后拋出的異常是ConstraintViolationException,get請求的對象參數校驗失敗后拋出的異常是BindException,post請求的對象參數校驗失敗后拋出的異常是MethodArgumentNotValidException,不同異常對象的結構不同,對異常消息的提取方式也就不同。如下圖所示:

1)MissingServletRequestParameterException

  1. if(e instanceof MissingServletRequestParameterException){    Result result = Result.buildErrorResult(ErrorCodeEnum.PARAM_ILLEGAL);    String msg = MessageFormat.format("缺少參數{0}", ((MissingServletRequestParameterException) e).getParameterName());    result.setMessage(msg);    return result;} 

2)ConstraintViolationException異常

  1. if(e instanceof ConstraintViolationException){  // 單個參數校驗異常  Result result = Result.buildErrorResult(ErrorCodeEnum.PARAM_ILLEGAL);  Set<ConstraintViolation<?>> sets = ((ConstraintViolationException) e).getConstraintViolations();  if(CollectionUtils.isNotEmpty(sets)){    StringBuilder sb = new StringBuilder();    sets.forEach(error -> {                    if (error instanceof FieldError) {                        sb.append(((FieldError)error).getField()).append(":");                    }                    sb.append(error.getMessage()).append(";");                });    String msg = sb.toString();    msg = StringUtils.substring(msg, 0, msg.length() -1);    result.setMessage(msg);  }  return result;} 

3)BindException異常

  1. if (e instanceof BindException){      // get請求的對象參數校驗異常      Result result = Result.buildErrorResult(ErrorCodeEnum.PARAM_ILLEGAL);      List<ObjectError> errors = ((BindException) e).getBindingResult().getAllErrors();      String msg = getValidExceptionMsg(errors);      if (StringUtils.isNotBlank(msg)){        result.setMessage(msg);      }      return result;} 

  1. private String getValidExceptionMsg(List<ObjectError> errors) {  if(CollectionUtils.isNotEmpty(errors)){    StringBuilder sb = new StringBuilder();    errors.forEach(error -> {                    if (error instanceof FieldError) {                       sb.append(((FieldError)error).getField()).append(":");                    }                    sb.append(error.getDefaultMessage()).append(";");                });    String msg = sb.toString();    msg = StringUtils.substring(msg, 0, msg.length() -1);    return msg;  }  return null;} 

4)MethodArgumentNotValidException異常

  1. if (e instanceof MethodArgumentNotValidException){      // post請求的對象參數校驗異常      Result result = Result.buildErrorResult(ErrorCodeEnum.PARAM_ILLEGAL);      List<ObjectError> errors = ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors();      String msg = getValidExceptionMsg(errors);      if (StringUtils.isNotBlank(msg)){        result.setMessage(msg);      }      return result;} 

 

責任編輯:梁菲 來源: 阿里云云棲號
相關推薦

2021-08-10 15:11:27

Spring Boot參數校驗

2022-11-10 07:53:54

Spring參數校驗

2025-05-27 07:07:29

2024-08-06 11:17:58

SpringJSON數據

2021-10-22 14:50:23

Spring BootJava

2023-03-09 12:04:38

Spring文件校驗

2025-04-29 07:44:26

配置校驗機制

2023-03-16 08:23:33

2022-12-30 08:49:41

SpringBoot@Validated

2022-04-21 09:59:53

Nest參數校驗

2025-05-14 00:00:00

2023-03-28 08:07:12

2023-11-29 07:23:04

參數springboto

2024-06-19 10:04:15

ifC#代碼

2025-01-06 09:51:51

2023-09-27 08:14:56

2021-05-18 09:25:54

SpringBoot參數校驗

2022-05-03 10:43:43

SpringJava

2020-09-27 11:35:16

Spring BootStarterJava

2024-12-02 00:59:30

Spring
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩成人在线观看 | 天天插天天操 | 能看的av | 日日夜夜91 | 欧美在线一区二区三区 | 久久久国产精品 | 国产成人在线播放 | 亚洲人成一区二区三区性色 | 亚洲风情在线观看 | 日韩精品一区二区不卡 | 中文在线一区二区 | 国产精品久久久久aaaa九色 | 干干干日日日 | 免费视频二区 | 亚洲国产成人精品久久 | 欧美成人a∨高清免费观看 欧美日韩中 | 国精日本亚洲欧州国产中文久久 | 狠狠操狠狠干 | 日本视频在线播放 | av网址在线播放 | 日日干干| 91精品久久久久久久久 | www.日韩 | 久久在线| 国产综合精品 | 日韩成人高清在线 | 日韩三区在线 | 狠狠狠干| 在线观看毛片网站 | 久产久精国产品 | 国产成人精品久久二区二区91 | 日韩欧美一区二区三区 | 97偷拍视频 | 最新91在线 | 国产综合久久久久久鬼色 | 成人精品一区二区 | 伊人春色成人 | www.中文字幕.com | 国产黄色免费网站 | 91精品一区二区三区久久久久 | 亚洲国产成人精品久久久国产成人一区 |