SpringMVC參數校驗

使用SpringMVC時配合hibernate-validate進行參數的合法性校驗,能節省必定的代碼量。

 

1.搭建Web工程並引入hibernate-validate依賴

 

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.7.Final</version>
</dependency> 

 

Maven依賴傳遞,自動依賴validation-api、jboss-logging、classmate。前端

 

 

2.使用校驗註解標註在屬性上(DTO)

 

 

 

*每一個註解都有message屬性,該屬性用於填寫校驗失敗時的異常描述信息,當校驗失敗時能夠獲取對應的message屬性值。後端

 

public class User { @NotNull(message="id不能爲空!") private Integer id; @NotBlank(message="用戶名不能爲空!")
@Size(min=4,max=12,message="用戶名的長度在4~12之間!")
private String username; @NotBlank(message="密碼不能爲空!") private String password; @Email(message="非法郵箱!") private String email; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public User() { super(); } }

 

 

3.控制層中使用DTO接收參數並使用@Validated/@Valid註解開啓對參數的校驗

 

*@Validated註解表示開啓Spring的校驗機制,支持分組校驗,聲明在入參上。api

*@Valid註解表示開啓Hibernate的校驗機制,不支持分組校驗,聲明在入參上。數組

*在DTO後面緊跟BindingResult對象,那麼當參數不符合時,能經過該對象直接獲取不符合校驗的message描述信息。app

*若使用了@Validated/@Valid註解開啓校驗,但DTO後面沒有緊跟BindingResult對象,那麼當參數不符合時,將直接返回400 Bad Request狀態碼。 this

 

@RestController public class BaseController { @RequestMapping("/test") public User test(@Validated User user, BindingResult result) { if (result.hasErrors()) { List<ObjectError> errors = result.getAllErrors(); for (ObjectError error : errors) { System.out.println(error.getDefaultMessage()); } } return user; } }

 

演示:spa

 

 結果:hibernate

密碼不能爲空! id不能爲空! 用戶名的長度在4~12之間!

 

*校驗的順序是隨機的,所以程序不能依賴校驗的順序去作相關的邏輯處理。code

 

 

4.分組校驗

 

每一個校驗註解都有group屬性用於指定校驗所屬的組,其值是Class數組,在Controller中使用@Validated註解開啓對參數的校驗時若指定要進行校驗的組,那麼只有組相同的屬性纔會被進行校驗(默認全匹配)對象

Class<?>[] groups() default { };

 

通常定義標識接口做爲組資源

public interface GroupA { } public interface GroupB { }

 

使用校驗註解標註在屬性上並進行分組

public class User { @NotNull(message="id不能爲空!",groups = {GroupA.class}) private Integer id; @NotBlank(message="用戶名不能爲空!",groups = {GroupB.class}) @Size(min=4,max=12,message="用戶名的長度在4~12之間!") private String username; @NotBlank(message="密碼不能爲空!") private String password; @Email(message="非法郵箱!") private String email; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public User() { super(); } }

 

 Controller中使用@Validated註解開啓對參數的校驗並指定校驗的組,那麼只有組相同的屬性纔會被進行校驗(默認全匹配)

@RestController public class BaseController { @RequestMapping("/test") public User test(@Validated(value= {GroupB.class}) User user, BindingResult result) { if (result.hasErrors()) { List<ObjectError> errors = result.getAllErrors(); for (ObjectError error : errors) { System.out.println(error.getDefaultMessage()); } } return user; } }

 

演示:

 

結果:

用戶名不能爲空!

 

*後端通常只返回重名等錯誤描述信息,對於非空、字符長度、手機郵箱合法性校驗等由前端進行判斷並提示,後端校驗不經過時不返回錯誤描述信息,因此不須要使用BindingResult獲取錯誤描述,當參數不符合時直接返回400 Bad Request請求。

相關文章
相關標籤/搜索