spring boot 1.4默認使用 hibernate validator 5.2.4 Final實現校驗功能。hibernate validator 5.2.4 Final是
JSR 349 Bean Validation 1.1的具體實現。
一 初步使用
hibernate vilidator主要使用註解的方式對bean進行校驗,初步的例子如下所示:
- package com.learn.validate.domain;
- import javax.validation.constraints.Min;
- import org.hibernate.validator.constraints.NotBlank;
- public class Student {
- //在需要校驗的字段上指定約束條件
- @NotBlank
- private String name;
- @Min(3)
- private int age;
- @NotBlank
- private String classess;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getClassess() {
- return classess;
- }
- public void setClassess(String classess) {
- this.classess = classess;
- }
- }
然後在controller中可以這樣調用,加上@Validated註解即可。
- package com.learn.validate.controller;
- import org.springframework.validation.annotation.Validated;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import com.learn.validate.domain.Student;
- @RestController
- public class ValidateController {
- @RequestMapping(value="testStudent")
- public void testStudent(@Validated Student student) {
- }
- }
如果校驗失敗,默認會返回Spring boot 框架的出錯信息。是一個json串,裏面有詳細的出錯描述。
二 使用gruops 屬性來實現區別不同的校驗需求
在上面的例子中,如果Student bean想要用於兩個不同的請求中,每個請求有不同的校驗需求,例如一個
請求只需要校驗name字段,一個請求需要校驗name和age兩個字段,那該怎麼做呢?
使用註解的groups屬性可以很好的解決這個問題,如下所示:
- package com.learn.validate.domain;
- import javax.validation.constraints.Min;
- import org.hibernate.validator.constraints.NotBlank;
- public class Student {
- //使用groups屬性來給分組命名,然後在需要的地方指定命令即可
- @NotBlank(groups=NAME.class)
- private String name;
- @Min(value=3,groups=AGE.class)
- private int age;
- @NotBlank
- private String classess;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getClassess() {
- return classess;
- }
- public void setClassess(String classess) {
- this.classess = classess;
- }
- public interface NAME{};
- public interface AGE{};
- }
根據需要在@Validated屬性中指定需要校驗的分組名,可以指定1到多個。指定到的分組名會全部進行校驗
,不指定的不校驗。
- package com.learn.validate.controller;
- import org.springframework.validation.annotation.Validated;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import com.learn.validate.domain.Student;
- import com.learn.validate.domain.Student.AGE;
- import com.learn.validate.domain.Student.NAME;
- @RestController
- public class ValidateController {
- @RequestMapping(value="testStudent")
- public void testStudent(@Validated Student student) {
- }
- @RequestMapping(value="testStudent1")
- public void testStudent1(@Validated(NAME.class) Student student) {
- }
- @RequestMapping(value="testStudent2")
- public void testStudent2(@Validated({NAME.class,AGE.class})
- Student student) {
- }
- }
三 使用 @ScriptAssert 註解校驗複雜的業務邏輯
如果需要校驗的業務邏輯比較複雜,簡單的@NotBlank,@Min註解已經無法滿足需求了,這時可以使用 @ScriptAssert 來指定進行校驗的方法,通過方法來進行復雜業務邏輯的校驗,然後返回 true或false來表
明是否校驗成功。例如下面的例子:
- package com.learn.validate.domain;
- import javax.validation.constraints.Min;
- import org.hibernate.validator.constraints.NotBlank;
- import org.hibernate.validator.constraints.ScriptAssert;
- import com.learn.validate.domain.Student.CHECK;
- //通過script 屬性指定進行校驗的方法,傳遞校驗的參數,
- //依然可以通過groups屬性指定分組名稱
- @ScriptAssert(lang="javascript",script="com.learn.validate.domain
- .Student.checkParams(_this.name,_this.age,_this.classes)",
- groups=CHECK.class)
- public class Student {
- @NotBlank(groups=NAME.class)
- private String name;
- @Min(value=3,groups=AGE.class)
- private int age;
- @NotBlank
- private String classess;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getClassess() {
- return classess;
- }
- public void setClassess(String classess) {
- this.classess = classess;
- }
- public interface NAME{};
- public interface AGE{};
- public interface CHECK{};
- //注意進行校驗的方法要寫成靜態方法,否則會出現
- //TypeError: xxx is not a function 的錯誤
- public static boolean checkParams(String name,int age,String classes) {
- if(name!=null&&age>8&classes!=null)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
在需要的地方,通過分組名稱進行調用。
- package com.learn.validate.controller;
- import org.springframework.validation.annotation.Validated;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import com.learn.validate.domain.Student;
- import com.learn.validate.domain.Student.CHECK;
- @RestController
- public class ValidateController {
- @RequestMapping(value="testStudent3")
- public void testStudent3(@Validated(CHECK.class) Student student) {
- }
- }