一、什么時候使用@NotBlank注解
來源:https://blog.csdn.net/sunnyzyq/article/details/103527380
在Spring項目中,微服務之間常采用Restful接口。那么問題來了,當前段調用后端接口,或者后端微服務接口被其它微服務調用時,我們不可能只依賴接口調用方對參數准確性進行檢查,接口提供方也需要在入口對參數准確進行檢查。
如:接口中關鍵參數是個一個員工對象Employee為例,員工對象實體類定義如下:
public class Employee {
/** 姓名 */
public String name;
/** 年齡 */
public Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Contoller中定義一個增加員工的add接口,如下:
@Controller
public class TestController {
@RequestMapping("/add")
@ResponseBody
public String add(Employee employee) {
//TODO 保存到數據庫
return "新增員工成功";
}
}
現在,我們需要對接口參數進行檢查,需員工的名稱不能為空、且長度不超過10個字符,如何做呢?Controller中增加判斷如下:
@Controller
public class TestController {
@RequestMapping("/add")
@ResponseBody
public String add(Employee employee) {
String name = employee.getName();
if(name == Null || name.trim().length() == 0) {
return "員工名稱不能為空";
}
if(name.trim().length() > 0) {
return "員工名稱不能超過10個字符";
}
//TODO 保存到數據庫
return "新增員工成功";
}
}
運行測試,可以發現檢查結果符合預期。
現在,我們又需要增加對員工年齡的限制,必須在20~50歲。怎么辦呢?繼續在Controller中添加判斷:
@Controller
public class TestController {
@RequestMapping("/add")
@ResponseBody
public String add(Employee employee) {
String name = employee.getName();
if(name == Null || name.trim().length() == 0) {
return "員工名稱不能為空";
}
if(name.trim().length() > 0) {
return "員工名稱不能超過10個字符";
}
Integer age = employee.getAge();
if(age == Null) {
return "員工年齡不能為空";
}
if(age < 20 || age > 50) {
return "員工年齡不能小於20或大於50";
}
//TODO 保存到數據庫
return "新增員工成功";
}
}
那么問題來了,現在員工對象Employee就2個字段,我們就寫了10多行的代碼驗證,要是有20個字段,豈不是要寫100多行代碼?通常來說,當一個方法中的無效業務代碼量過多時,往往代碼設計有問題,當然這不是我們所想看到都結果。
有人會說,把對應的校驗過程抽象成獨立的驗證方法吧:
@Controller
public class TestController {
@RequestMapping("/add")
@ResponseBody
public String add(Employee employee) {
String result = vaild(employee);
if(result != Null) {
return result ;
}
//TODO 保存到數據庫
return "新增員工成功";
}
}
String valid(Employee employee) {
String name = employee.getName();
if(name == Null || name.trim().length() == 0) {
return "員工名稱不能為空";
}
if(name.trim().length() > 0) {
return "員工名稱不能超過10個字符";
}
Integer age = employee.getAge();
if(age == Null) {
return "員工年齡不能為空";
}
if(age < 20 || age > 50) {
return "員工年齡不能小於20或大於50";
}
return null;
}
這樣來看,我們的Controller業務方法就清爽多了。但本質上編碼量沒有減少,只是換了位置封裝。
Spring提供的@NotBlank、@valid很好實現如上消息valid檢查
- 使用@valid首先要要引入其依賴
- 如果是SpringBoot項目,引入web開發包,就不需要再單獨引入@valid依賴了、因為他存在於Web開發包中的最核心之中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
- 如果不是SpringBoot項目,要在Maven的Pom中顯式引入@valid依賴,如下:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
- 引入依賴后,如何使用呢?
- 在Employee實體類上加上注解:
public class Employee {
/** 姓名 */
@NotBlank(message = "請輸入名稱")
@Length(message = "名稱不能超過個 {max} 字符", max = 10)
public String name;
/** 年齡 */
@NotNull(message = "請輸入年齡")
@Range(message = "年齡范圍為 {min} 到 {max} 之間", min = 1, max = 100)
public Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
- 在Controller對應的參數上,加上@valid注解,如下:
public class TestController {
@RequestMapping("/add")
@ResponseBody
public String add(@valid Employee employee) {
//TODO 保存到數據庫
return "新增員工成功";
}
}
此時,Controller方法就會對@valid注解的參數 根據 類中的@NotBlank等注解進行檢查,檢查失敗,返回注解中message指定的消息。效果與前面自己寫代碼檢查一致。
【注】:@NotBlank等注解時,一定要和@valid一起使用,不然@NotBlank不起作用。
- 既然對參數進行了檢查,就肯定會有檢查結果。如果我們需要用一個東西來存放驗證結果,做法也很簡單,在參數直接添加一個BindingResult。如下:
public class TestController {
@RequestMapping("/add")
@ResponseBody
public String add(@valid Employee employee, BindingResult bindingResult) {
//TODO 保存到數據庫
return "新增員工成功";
}
}
*如果想獲取保存的驗證結果,樣例如下:
public class TestController {
@RequestMapping("/add")
@ResponseBody
public String add(@valid Employee employee, BindingResult bindingResult) {
//檢查所有字段是否驗證通過
if(bindingResult.hasErrors()) {
//驗證失敗,返回第一條錯誤信息
return bindingResult.getALLErrors().get(0).getDefaultMessage();
}
//TODO 保存到數據庫
return "新增員工成功";
}
}
二、類似@NotBlank使用方式的注解
@NotNull:不能為null,但可以為empty
@NotEmpty:不能為null,而且長度必須大於0
@NotBlank:只能作用在String上,不能為null,而且調用trim()后,長度必須大於0。(trim()刪除字符串的頭尾空白符)
樣例輔助理解:
1.String name = null;則注解檢查結果:
@NotNull: false
@NotEmpty:false
@NotBlank:false
2.String name = "";則注解檢查結果:
@NotNull:true
@NotEmpty: false
@NotBlank: false
3.String name = " ";則注解檢查結果:
@NotNull: true
@NotEmpty: true
@NotBlank: false
4.String name = "Great answer!";則注解檢查結果:
@NotNull: true
@NotEmpty:true
@NotBlank:true
其他注解:
@Length(message = "名稱不能超過個 {max} 字符", max = 10)
public String name;
/** 年齡 */
@Range(message = "年齡范圍為 {min} 到 {max} 之間",min = 1,max = 100)
public Integer age;
@Size(message = "興趣最多選擇{max}個", max = 5)
private List<String> hobbyList;