【SpringBoot】-@valid、@NotBlank、@NotEmpty、@NotNull注解使用場景及差別


一、什么時候使用@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檢查

  1. 使用@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>
  1. 引入依賴后,如何使用呢?
  • 在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;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM