最近開始由原來的Android工程師Java Web向轉型了,廢話很少說,上圖java
JSR 303 – Bean Validation 是一個數據驗證的規範,2009 年 11 月肯定最終方案。 Hibernate Validator 是 Bean Validation 的參考實現 . Hibernate Validator 提供了 JSR 303 規範中全部內置 constraint 咱們一般寫接口時會對傳來的參數進行校驗判斷,好比字符串非空判斷,值在多少返回等,這些就要用到Spring 的參數校驗,這裏咱們使用在spring-boot-starter-web包裏面有hibernate-validator包, 參數校驗有幾種方式,以下git
下面來介紹這兩種方式的使用web
Constraint 詳細信息
@Null 被註釋的元素必須爲 null
@NotNull 被註釋的元素必須不爲 null
@AssertTrue 被註釋的元素必須爲 true
@AssertFalse 被註釋的元素必須爲 false
@Min(value) 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值
@Max(value) 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值
@DecimalMin(value) 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值
@DecimalMax(value) 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值
@Size(max, min) 被註釋的元素的大小必須在指定的範圍內
@Digits (integer, fraction) 被註釋的元素必須是一個數字,其值必須在可接受的範圍內
@Past 被註釋的元素必須是一個過去的日期
@Future 被註釋的元素必須是一個未來的日期
@Pattern(value) 被註釋的元素必須符合指定的正則表達式
複製代碼
/**
* @author Lang.Chen
* @date 2018/6/20 下午4:39
*/
public class User {
//帳號
@NotBlank(message = "帳號不能爲空")
private String phone;
//密碼
@NotBlank(message = "密碼不能爲空")
private String password;
public void setPhone(String phone) {
this.phone = phone;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public String getPassword() {
return password;
}
}
複製代碼
if(bindingResult.hasErrors()){
}
複製代碼
@RestController
@RequestMapping(value = "/user")
public class UserController implements IUser {
@Override
@RequestMapping(value = "/login", method = RequestMethod.POST)
public User login( @Valid User userInfo, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
System.out.print(bindingResult.getFieldError().getDefaultMessage());
return null;
}
return userInfo;
}
}
複製代碼
好了,第一種驗證咱們已經說完了,但你仔細想一想,若是我有多個接口,是否是每次有要寫@Valid+BindgResult bingingResult,而後再到If語句裏面進行判斷,若是僅僅是錯誤信息不一致,但返回的客戶端結構是一致的,好比正則表達式
{"code":"1002","message":"parameters are missing","data":"{}"}
複製代碼
不一樣的驗證只要改變message,那麼是否是能夠統一處理,來減小代碼量,因而下面介紹第二種方式spring
簡單點說,由第一種方式去掉BindingResult,而後再定義一個全局異常類,一樣的bash
/**
* @author Lang.Chen
* @date 2018/6/20 下午4:39
*/
public class User {
//帳號
@NotBlank(message = "帳號不能爲空")
private String phone;
//密碼
@NotBlank(message = "密碼不能爲空")
private String password;
public void setPhone(String phone) {
this.phone = phone;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public String getPassword() {
return password;
}
}
複製代碼
public class UserController implements IUser {
@Override
@RequestMapping(value = "/login2", method = RequestMethod.POST)
public User login2(@RequestBody @Valid User userInfo) {
return null;
}
}
複製代碼
全部驗證失敗的結果都會在GlobleExceptionHandler的defultExcepitonHandler方法裏面捕捉到app
@RestControllerAdvice
@Component
public class GlobleExceptionHandler {
@ResponseBody
@ExceptionHandler(Exception.class)
public String defultExcepitonHandler(Exception ex) {
ex.printStackTrace();
if(ex instanceof BindException){
//處理返回的錯誤信息
StringBuffer errorMsg = new StringBuffer();
BindException c = (BindException) ex;
List<ObjectError> errors = c.getBindingResult().getAllErrors();
for (ObjectError error : errors) {
errorMsg.append(error.getDefaultMessage()).append(";");
}
return errorMsg.toString();
}
return "";
}
}
複製代碼
有關於自定義驗證和分組驗證,就不一一介紹了,會使用以上2個就能夠了。ide
有時候只傳入少數驗證時,咱們不可能都是新建一個對象來接受,這時候如何使用單個參數驗證呢,看到網上使用在類上添加 @Validated參數,而後經過全局異常捕捉方式spring-boot
@RestController
@RequestMapping("/order")
@Validated
public class OrderController implements IOrder {
@RequestMapping(value = "/byId",method = RequestMethod.POST)
public OrderInfo byId( @Max(value = 50) int orderId) {
return null;
}
}
複製代碼
但每次訪問接口時,都是報同一個錯誤,就沒用這個方式了,若是有人找到解決方案,請指教,謝謝ui
{
"timestamp": "2018-06-24T07:09:14.235+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/order/byId"
}
複製代碼
@Valid是javax.validation裏的 @Validated是@Valid 的一次封裝,是Spring提供的校驗機制使用。@Validated 提供分組功能