Spring Boot在內(nèi)部通過集成hibernate-validation實現(xiàn)了JSR-349驗證規(guī)范接口,我們可以在MVC模式中對DTO進行靈活的校驗,代碼看起來也會更簡潔、更優(yōu)雅.
參考地址:https://docs.jboss.org/hibernate/stable/validator/reference/en-US/pdf/hibernate_validator_reference.pdf
常用注解列表
| @AssertTrue | 用于boolean字段,該字段只能為true |
|---|---|
| @AssertFalse | 該字段的值只能為false |
| @CreditCardNumber | 對信用卡號進行一個大致的驗證 |
| @DecimalMax | 只能小于或等于該值 |
| @DecimalMin | 只能大于或等于該值 |
| @Digits(integer=,fraction=) | 檢查是否是一種數(shù)字的整數(shù)、分數(shù),小數(shù)位數(shù)的數(shù)字 |
| 檢查是否是一個有效的email地址 | |
| @Future | 檢查該字段的日期是否是屬于將來的日期 |
| @Length(min=,max=) | 檢查所屬的字段的長度是否在min和max之間,只能用于字符串 |
| @Max | 該字段的值只能小于或等于該值 |
| @Min | 該字段的值只能大于或等于該值 |
| @NotNull | 不能為null |
| @NotBlank | 不能為空,檢查時會將空格忽略 |
| @NotEmpty | 不能為空,這里的空是指空字符串 |
| @Null | 檢查該字段為空 |
| @Past | 檢查該字段的日期是在過去 |
| @Pattern(regex=,flag=) | 被注釋的元素必須符合指定的正則表達式 |
| @Range(min=,max=,message=) | 被注釋的元素必須在合適的范圍內(nèi) |
| @Size(min=, max=) | 檢查該字段的size是否在min和max之間,可以是字符串、數(shù)組、集合、Map等 |
| @URL(protocol=,host,port) | 檢查是否是一個有效的URL,如果提供了protocol,host等,則該URL還需滿足提供的條件 |
| @Valid | 該注解主要用于字段為一個包含其他對象的集合或map或數(shù)組的字段,或該字段直接為一個其他對象的引用,這樣在檢查當前對象的同時也會檢查該字段所引用的對象 |
maven依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!--Jackson,用于前端傳過來的json字符串,對其序列號和反序列化-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
controller控制層
package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.model.Result;
import com.example.demo.model.Student;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
public class ValidationItemException {
@PostMapping(value = "/validation/save")
public Result saveStudentPage(@Valid @RequestBody Student student) {
return new Result(200, "", JSONObject.toJSON(student).toString());
}
@PostMapping(value = "/validation/save2")
public Student saveStudentPage2(@Valid @RequestBody Student student) {
return student;
}
}
DTO實體層(Student)
1.錯誤信息統(tǒng)一管理
我們也可以把錯誤信息message定制化到配置文件message.properties里面統(tǒng)一管理
2.@Valid和@Validated的區(qū)別
@Valid是javax.validation里的 @Validated是@Valid 的一次封裝,是Spring提供的校驗機制使用。@Validated 提供分組功能,但是在校驗項比較多的情況下,本人不是很推薦分組校驗,因為在開發(fā)中容易出錯.
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Future;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
public class Student {
@Range(min=15,max=65,message = "年齡必須在15歲到65歲")
private int age;
@Size(min=2, max=30)
private String name;
@NotEmpty(message = "自定義錯誤信息,score不能為空!")
private String score;
@Future(message = "生效時間必須大于當前時間")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getScore() {
return score;
}
public void setScore(String score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", score='" + score + '\'' +
'}';
}
}
DTO實體層(Result)
package com.example.demo.model;
public class Result implements java.io.Serializable{
private int code;
private String msg;
private Object data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
全局異常捕獲
package com.example.demo.Hanlder;
import com.example.demo.model.Result;
import org.springframework.http.HttpStatus;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.List;
import java.util.stream.Collectors;
@RestControllerAdvice
public class BindExceptionHandler {
/**
* 全局異常捕捉處理
*
* @param ex
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handleBindException(MethodArgumentNotValidException ex) {
// 同樣是獲取BindingResult對象,然后獲取其中的錯誤信息
// 如果前面開啟了fail_fast,事實上這里只會有一個信息
//如果沒有,則可能又多個
List<String> errorInformation = ex.getBindingResult().getAllErrors()
.stream()
.map(ObjectError::getDefaultMessage)
.collect(Collectors.toList());
return new Result(HttpStatus.BAD_REQUEST.value(),errorInformation.toString(),null) ;
}
}
測試結(jié)果

image.png