
前言
在日常的開發中,參數校驗是非常重要的一個環節,嚴格參數校驗會減少很多出bug的機率,增加接口的安全性。也會減少對接時不必要的溝通。比如說:在對接的時候前端動不動就甩個截圖過來說接口有問題,你檢查了半天發現前端傳遞的參數有問題。針對以上:今天給大家分享一下SpringBoot如何實作統一參數校驗。
實作方式
使用
@Validated
注解配合參數校驗注解, 比如:
@NotEmpty
對參數進行校驗。然後對抛出的異常
ControllerAdvice
進行捕獲然後調整輸出資料。
TestController
@RestController
public class TestController {
/**
* 表單請求
* @param form 請求參數
* @return 響應資料
*/
@PostMapping("/formRequest")
public ResultVo formRequest(@Validated RequestForm form){
return ResultVoUtil.success(form);
}
/**
* JSON請求
* @param form 請求參數
* @return 響應資料
*/
@PostMapping("/jsonRequest")
public ResultVo jsonRequest(@RequestBody @Validated RequestForm form){
return ResultVoUtil.success(form);
}
}
RequestForm
@Data
public class RequestForm {
@NotEmpty(message = "姓名不能為空")
private String name;
@Min(value = 1 , message = "年齡不能小于1歲")
private Integer age;
@NotEmpty(message = "性别不能為空")
private Integer sex;
}
測試結果
請求:
http://localhost:8080/formRequest不傳任何參數。
這個時候SpringBoot已經根據校驗注解對參數進行校驗了。并且輸出了一大堆的錯誤資訊。這個時候前端在對接的時候看到這樣的錯誤資訊,反手就是給你截個圖告訴你接口有問題。是以這個時候就該使用
ControllerAdvice
規範異常傳回資訊了。
ControllerAdvice
@Slf4j
@RestControllerAdvice
public class ControllerAdvice {
/**
* 攔截表單參數校驗
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler({BindException.class})
public ResultVo bindException(BindException e) {
BindingResult bindingResult = e.getBindingResult();
return ResultVoUtil.error(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
}
/**
* 攔截JSON參數校驗
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultVo bindException(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
return ResultVoUtil.error(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
}
}
@RestControllerAdvice會将傳回的資料以json輸出,如果不需要可以使用@ControllerAdvice
以上代碼隻傳回了錯誤資訊。可以根據實際情況進行調整。
這個時候的錯誤資訊就比較友好了,非常明确的指出了缺少參數。
常用校驗注解
注解 | 運作時檢查 |
---|---|
@AssertFalse | 被注解的元素必須為false |
@AssertTrue | 被注解的元素必須為true |
@DecimalMax(value) | 被注解的元素必須為一個數字,其值必須小于等于指定的最小值 |
@DecimalMin(Value) | 被注解的元素必須為一個數字,其值必須大于等于指定的最小值 |
@Digits(integer=, fraction=) | 被注解的元素必須為一個數字,其值必須在可接受的範圍内 |
@Future | 被注解的元素必須是日期,檢查給定的日期是否比現在晚 |
@Max(value) | |
@Min(value) | |
@NotNull | 被注解的元素必須不為null |
@Null | 被注解的元素必須為null |
@Past(java.util.Date/Calendar) | 被注解的元素必須過去的日期,檢查标注對象中的值表示的日期比目前早 |
@Pattern(regex=, flag=) | 被注解的元素必須符合正規表達式,檢查該字元串是否能夠在match指定的情況下被regex定義的正規表達式比對 |
@Size(min=, max=) | 被注解的元素必須在制定的範圍(資料類型:String, Collection, Map and arrays) |
@Valid | 遞歸的對關聯對象進行校驗, 如果關聯對象是個集合或者數組, 那麼對其中的元素進行遞歸校驗,如果是一個map,則對其中的值部分進行校驗 |
@CreditCardNumber | 對信用卡号進行一個大緻的驗證 |
被注釋的元素必須是電子郵箱位址 | |
@Length(min=, max=) | 被注解的對象必須是字元串的大小必須在制定的範圍内 |
@NotBlank | 被注解的對象必須為字元串,不能為空,檢查時會将空格忽略 |
@NotEmpty | 被注釋的對象必須為空(資料:String,Collection,Map,arrays) |
@Range(min=, max=) | 被注釋的元素必須在合适的範圍内 (資料:BigDecimal, BigInteger, String, byte, short, int, long and 原始類型的包裝類 ) |
@URL(protocol=, host=, port=, regexp=, flags=) | 被注解的對象必須是字元串,檢查是否是一個有效的URL,如果提供了protocol,host等,則該URL還需滿足提供的條件 |
案例
@Data
public class ExampleForm {
@NotEmpty(message = "姓名不能為空")
@Length(min = 1 , max = 10 , message = "名字長度1~10")
private String name;
@Range(min = 1 , max = 99 , message = "年齡範圍在1~99歲")
private Integer age;
@Pattern(regexp = "^[1][3,4,5,7,8][0-9]{9}$" , message = "電話号碼有誤")
private String phone;
@Email(message = "郵箱格式有誤")
private String email;
@Valid
@Size(min = 1 ,max = 10 , message = "清單中的元素數量為1~10")
private List<RequestForm> requestFormList;
@Future(message = "開始時間必須大于目前時間")
private Date beginTime;
}
實作嵌套驗證
在實際的開發中,前台會背景傳遞一個list,我們不僅要限制每次請求list内的個數,同時還要對list内基本元素的屬性值進行校驗。這個時候就需要進行嵌套驗證了,實作的方式很簡單。在list上添加@Vaild就可以實作了。
@Data
public class JsonRequestForm {
@Vaild
@Size(min = 1 ,max = 10 , message = "清單中的元素數量為1~10")
private List<RequestForm> requestFormList;
}
代碼位址
https://gitee.com/huangxunhui/unifiedParamCheck.git
結尾
如果覺得對你有幫助,可以多多評論,多多點贊哦,也可以到我的首頁看看,說不定有你喜歡的文章,也可以随手點個關注哦,謝謝。
我是不一樣的科技宅,每天進步一點點,體驗不一樣的生活。我們下期見!