Spring Validator介面提供了一種靈活且可自定義的方法來驗證物件。在本文中,我們學習如何使用Validator介面在基於 Spring 的應用程式中驗證物件。我們探索了Validator介面的兩種方法supports()和verify(),以及如何實現自定義驗證器來驗證物件。
什麼是Spring Validator介面
Validator介面是Spring 框架的一部分,它提供了一種驗證物件的方法。
它是一個簡單的介面,定義了兩個方法,supports()和verify()。這兩個方法用於確定驗證器是否可以驗證物件並執行驗證邏輯。
支援(Class<?> clazz)
Validator介面中的 supports() 方法確定驗證器是否可以驗證特定類的例項。此方法接受一個引數Class<?> clazz,該參數列示被驗證物件的類。它是一個通用類 ( Class<?> ),可以靈活地處理不同的物件型別。
具體來說,Spring 使用isAssignableFrom()方法來檢查一個物件是否可以合法地轉換為驗證器支援的類的物件。因此,如果驗證器可以處理提供的clazz的物件,則返回true,否則,返回false以指示應使用另一個驗證器:
@Override public boolean supports(Class<?> clazz) { return User.class.isAssignableFrom(clazz); }
|
在此示例中,驗證器配置為僅支援驗證User型別或其子類的物件。方法isAssignableFrom()透過繼承驗證相容性 - 它對 User 及其子類返回true ,對任何其他類型別返回false。驗證(物件目標,錯誤錯誤)
另一方面,validate()方法在 Spring 的驗證框架中起著至關重要的作用。我們在這裡為驗證器支援的物件定義自定義驗證邏輯。
該方法接收兩個關鍵引數:
- Object target:此參數列示要驗證的實際物件。Spring MVC會自動將我們要驗證的物件傳遞給此方法。
- Errors :此引數是Errors介面的一個例項。它提供了向物件新增驗證錯誤的各種方法。
以下是validate()方法的一個示例:@Override public void validate(Object target, Errors errors) { User user = (User) target; if (StringUtils.isEmpty(user.getName())) { errors.rejectValue(<font>"name", "name.required", "Name cannot be empty"); } }
|
在此示例中,validate()方法對User物件執行各種驗證,並使用rejectionValue()將特定錯誤訊息新增到Errors物件以識別目標欄位錯誤。值得注意的是,rejectValue()有三個主要引數:
- field:出現錯誤的欄位名稱,例如“ name ”
- errorCode:標識錯誤的唯一程式碼,例如“ name.required ”
- defaultMessage:如果未找到其他訊息,則顯示預設錯誤訊息,例如“名稱不能為空”
實現驗證器
要建立驗證器,我們需要實現Validator介面。下面是驗證User物件的簡單驗證器示例:public class UserValidator implements Validator { @Override public boolean supports(Class<?> clazz) { return User.class.isAssignableFrom(clazz); } @Override public void validate(Object target, Errors errors) { User user = (User) target; if (StringUtils.isEmpty(user.getName())) { errors.rejectValue(<font>"name", "name.required", "Name cannot be empty"); } if (StringUtils.isEmpty(user.getEmail())) { errors.rejectValue("email", "email.required", "Invalid email format"); } } }
|
建立使用者類
在應用驗證之前,必須定義我們要驗證的物件的結構。以下是User類的一個示例:
public class User { private String name; private String email; <font>// Getters and Setters<i> }
|
配置 Spring Bean
接下來,為了將自定義驗證器整合到基於 Spring 的應用程式中,我們可以使用 Spring 配置類將其註冊為應用程式上下文中的 bean。此註冊可確保驗證器在整個應用程式生命週期內可用於依賴項注入:
@Configuration public class AppConfig implements WebMvcConfigurer{ @Bean public UserValidator userValidator() { return new UserValidator(); } }
|
透過用@Bean註釋userValidator()方法,我們確保它返回 Spring 在應用程式上下文中註冊為 bean 的物件。在 Spring MVC 控制器中整合驗證器
一旦我們註冊了驗證器,我們就可以使用它來驗證Spring MVC 控制器中的使用者物件。
接下來我們建立一個UserController來處理與使用者相關的請求:
@RestController @RequestMapping(<font>"/api/users") public class UserController { @Autowired private UserValidator userValidator; @PostMapping public ResponseEntity<?> createUser(@RequestBody User user) { Errors errors = new BeanPropertyBindingResult(user, "user"); userValidator.validate(user, errors); if (errors.hasErrors()) { return ResponseEntity.badRequest().body(errors.getAllErrors()); } // Save the user object to the database<i> return ResponseEntity.ok("User created successfully!"); } }
|
在此示例中,我們使用 Spring 的@RestController註釋來指示此控制器返回JSON響應。此外,我們使用@RequestBody將傳入的 JSON 請求正文繫結到User物件。如果驗證失敗,我們將返回 400 Bad Request 響應,其 JSON 正文包含錯誤訊息。否則,我們將返回 200 OK 響應,其中包含成功訊息。使用 Curl 進行測試
為了使用 curl 測試此 API,我們可以傳送包含User物件資料的 JSON 請求正文:
curl -X POST \ http:<font>//localhost:8080/api/users \<i> -H 'Content-Type: application/json' \ -d '{"name":"","email":""}'
|
這應該返回一個 400 Bad Request 響應,其 JSON 主體包含錯誤訊息:[ { <font>"codes": [ "name.required.user.name", "name.required.name", "name.required.java.lang.String", "name.required" ], "arguments": null, "defaultMessage": "Name cannot be empty", "objectName": "user", "field": "name", "rejectedValue": "", "bindingFailure": false, "code": "name.required" }, { "codes": [ "email.required.user.email", "email.required.email", "email.required.java.lang.String", "email.required" ], "arguments": null, "defaultMessage": "Invalid email format", "objectName": "user", "field": "email", "rejectedValue": "", "bindingFailure": false, "code": "email.required" } ]
|
如果我們傳送一個帶有姓名和電子郵件的有效使用者物件,API 應該返回 200 OK 響應以及成功訊息:curl -X POST \ http:<font>//localhost:8080/api/users \<i> -H 'Content-Type: application/json' \ -d '{"name":"John Doe","email":"johndoe@example.com"}'
|
結果,請求返回了帶有成功訊息的響應:<font>"User created successfully!"
|
驗證上下文
此外,在某些情況下,我們可能希望將其他上下文傳遞給驗證器。Spring的Validator介面透過validate(Object target, Errors errors, Object…validationHints)方法支援驗證上下文。因此,要使用驗證上下文,我們可以在呼叫validate()方法時傳遞其他物件作為驗證提示。
例如,我們想根據特定場景驗證使用者物件:
public void validate(Object target, Errors errors, Object... validationHints) { User user = (User) target; if (validationHints.length > 0) { if (validationHints[0] == <font>"create") { if (StringUtils.isEmpty(user.getName())) { errors.rejectValue("name", "name.required", "Name cannot be empty"); } if (StringUtils.isEmpty(user.getEmail())) { errors.rejectValue("email", "email.required", "Invalid email format"); } } else if (validationHints[0] == "update") { // Perform update-specific validation<i> if (StringUtils.isEmpty(user.getName()) && StringUtils.isEmpty(user.getEmail())) { errors.rejectValue("name", "name.or.email.required", "Name or email cannot be empty"); } } } else { // Perform default validation<i> } }
|
在此示例中,UserValidator檢查validationHints陣列以確定要使用哪種驗證方案。讓我們更新UserController以使用帶有validationHints的UserValidator:@PutMapping(<font>"/{id}") public ResponseEntity<?> updateUser(@PathVariable Long id, @RequestBody User user) { Errors errors = new BeanPropertyBindingResult(user, "user"); userValidator.validate(user, errors, "update"); if (errors.hasErrors()) { return ResponseEntity.badRequest().body(errors.getAllErrors()); } // Update the user object in the database<i> return ResponseEntity.ok("User updated successfully!"); }
|
現在,讓我們傳送以下curl命令,其中名稱和電子郵件欄位均為空:curl -X PUT \ http:<font>//localhost:8080/api/users/1 \<i> -H 'Content-Type: application/json' \ -d '{"name":"","email":""}'
|
UserValidator返回 400 Bad Request 響應並帶有錯誤訊息:[ { <font>"codes": [ "name.or.email.required.user.name", "name.or.email.required.name", "name.or.email.required.java.lang.String", "name.or.email.required" ], "arguments": null, "defaultMessage": "Name or email cannot be empty", "objectName": "user", "field": "name", "rejectedValue": "", "bindingFailure": false, "code": "name.or.email.required" } ]
|
如果我們只傳遞其中一個欄位,例如名稱欄位,那麼UserValidator允許更新繼續:curl -X PUT \ http:<font>//localhost:8080/api/users/1 \<i> -H 'Content-Type: application/json' \ -d '{"name":"John Doe"}'
|
響應是200 OK響應,表示更新成功:"User updated successfully!"