Springboot統一參數驗證方式
Springboot統一驗證方式
在提供http api 接口形式的服務中,通過都會傳遞參數為一個對象。我們需要對這個對象的各個字段進行校驗。來判斷是否為合法值。
傳統的方式為自己獲取每個字段的值,自己寫方法進行判斷。
這種方式太過麻煩。
推薦使用
推薦使用 validation 通過其JSR303 Java 規範提案 的驗證方法來進行驗證。進行簡化。
@Null 限制只能為null
@NotNull 限制必須不為null
@AssertFalse 限制必須為false
@AssertTrue 限制必須為true
@DecimalMax(value) 限制必須為一個不大於指定值的數字
@DecimalMin(value) 限制必須為一個不小於指定值的數字
@Digits(integer,fraction) 限制必須為一個小數,且整數部分的位數不能超過integer,小數部分的位數不能超過fraction
@Future 限制必須是一個將來的日期
@Max(value) 限制必須為一個不大於指定值的數字
@Min(value) 限制必須為一個不小於指定值的數字
@Past 限制必須是一個過去的日期
@Pattern(value) 限制必須符合指定的正則表達式
@Size(max,min) 限制字符長度必須在min到max之間
@Past 驗證註解的元素值(日期類型)比當前時間早
@NotEmpty 驗證註解的元素值不為null且不為空(字符串長度不為0、集合大小不為0)
@NotBlank 驗證註解的元素值不為空(不為null、去除首位空格後長度為0),不同於@NotEmpty,@NotBlank只應用於字符串且在比較時會去除字符串的空格
@Email 驗證註解的元素值是Email,也可以通過正則表達式和flag指定自定義的email格式
如不滿足還可以自定義驗證註解。
使用方式:
public class user
{
@NotNull(message = "姓名不可為空")
private String name;
@DecimalMin(value = "100",message = "年齡必須大於100")
private Integer age;
}
public user create(@RequestBody @Valid user u) {}
這裏有個問題,@Valid 如果有驗證不通過的約束。將會拋出一個異常,這個異常將直接響應。
響應json結構:
{
"timestamp": 1554169655057,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.web.bind.MethodArgumentNotValidException",
"errors": [
{
"codes": [
"NotNull.user.name",
"NotNull.name",
"NotNull.java.lang.String",
"NotNull"
],
"arguments": [
{
"codes": [
"user.name",
"name"
],
"arguments": null,
"defaultMessage": "name",
"code": "name"
}
],
"defaultMessage": "姓名不可為空",
"objectName": "user",
"field": "name",
"rejectedValue": null,
"bindingFailure": false,
"code": "NotNull"
}
],
"message": "Validation failed for object=‘user‘. Error count: 1",
"path": "/a"
}
這種方式在http api 的情況下非常不優化。
驗證異常統一處理攔截器
我們可以提供自定義異常攔截器來實現對這個異常的補貨,返回統一約定的響應結構體。
@ControllerAdvice
public class ExceptionControllerAdvice
{
/**
* 對驗證約束異常進行攔截,返回約定的響應體
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ZjsResponseEntity bindExceptionHandler(MethodArgumentNotValidException ex) {
BindingResult bindingResult = ex.getBindingResult();
List<ObjectError> errors = bindingResult.getAllErrors();
StringBuffer buffer = new StringBuffer();
for (ObjectError error : errors) {
buffer.append(error.getDefaultMessage()).append(" ");
}
return new ZjsResponseEntity("403", buffer.toString());
}
/**
* 參數類型轉換錯誤
*/
@ExceptionHandler(HttpMessageConversionException.class)
@ResponseBody
public ZjsResponseEntity parameterTypeException(HttpMessageConversionException exception) {
return new ZjsResponseEntity("403", exception.getCause().getLocalizedMessage());
}
}
這樣我們就可以簡化對請求參數的校驗了。
Springboot統一參數驗證方式