1. 引言
Spring Validator 接口提供了一種靈活且可定製的方式來驗證對象。在本教程中,我們將探討如何使用 Validator 接口在 Spring 應用程序中驗證對象。
2. Spring 驗證器接口
Spring 框架中的 驗證器 接口提供了一種驗證對象的方法。
這是一個簡單的接口,定義了兩個方法:supports() 和 validate()。 這兩個方法用於確定驗證器是否可以驗證對象以及執行驗證邏輯。
2.1. supports(Class<?> clazz)
supports() 方法在 Validator 接口中確定驗證器是否可以驗證特定類的實例。該方法接受一個參數 Class<?> clazz,它代表要驗證的對象所對應的類。這是一個泛型類 (Class<?>),以便支持不同類型的對象。
該方法利用 isAssignableFrom() 方法來檢查對象是否可以合法地轉換為驗證器支持的類。因此,如果驗證器可以處理提供的 clazz 類型的對象,則返回 true,否則返回 false 以指示應使用另一個驗證器。
@Override
public boolean supports(Class<?> clazz) {
return User.class.isAssignableFrom(clazz);
}在本示例中,驗證器僅配置為支持驗證 User 類型及其子類的對象。 isAssignableFrom() 方法通過繼承驗證兼容性——它對於 User 及其子類返回 true,對於任何其他類類型返回 false。
2.2. <em validate(Object target, Errors errors)</em>
該方法在 Spring 的驗證框架中起着至關重要的作用。它正是定義驗證器支持的對象的自定義驗證邏輯的地方。
該方法接收兩個關鍵參數:
- `>`:此參數代表要進行驗證的實際對象。 Spring MVC 會自動將我們嘗試驗證的對象傳遞到此方法。
- `>`:此參數是一個 `> 接口的實例。它提供各種方法用於向對象添加驗證錯誤。
以下是 <em validate()</em> 方法的示例:
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
if (StringUtils.isEmpty(user.getName())) {
errors.rejectValue("name", "name.required", "Name cannot be empty");
}
}在本示例中,validate() 方法會對 User 對象執行各種驗證,並使用 rejectValue() 將特定字段的錯誤消息添加到 Errors 對象中。 值得注意的是,rejectValue() 接受三個主要參數:
- field: 字段名稱,例如 "name"
- errorCode: 錯誤代碼,用於唯一標識錯誤,例如 "name.required"
- defaultMessage: 如果未找到其他消息,則顯示默認錯誤消息,例如 "Name cannot be empty"
3. 實現驗證器
為了創建驗證器,我們需要實現 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("name", "name.required", "Name cannot be empty");
}
if (StringUtils.isEmpty(user.getEmail())) {
errors.rejectValue("email", "email.required", "Invalid email format");
}
}
}3.1. 創建 User 類
在進行驗證之前,定義我們想要驗證的對象的結構至關重要。以下是 User 類的示例:
public class User {
private String name;
private String email;
// Getters and Setters
}3.2. 配置 Spring Bean
接下來,要將自定義驗證器集成到基於 Spring 的應用程序中,可以使用 Spring 配置類將其註冊為 Bean,並在應用程序上下文中進行註冊。 這種註冊確保驗證器在應用程序生命週期中可供依賴注入。
@Configuration
public class AppConfig implements WebMvcConfigurer{
@Bean
public UserValidator userValidator() {
return new UserValidator();
}
}通過對 userValidator() 方法進行註解,使用 @Bean,我們確保它返回的對象會被 Spring 註冊為一個 Bean,並在應用程序上下文中註冊。
3.3. 在 Spring MVC 控制器中集成 Validator
一旦我們註冊了驗證器,我們就可以使用它在 Spring MVC 控制器中驗證一個 User 對象。
接下來,讓我們創建一個 UserController 來處理與用户相關的請求:
@RestController
@RequestMapping("/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
return ResponseEntity.ok("User created successfully!");
}
}在本示例中,我們使用 Spring 的 @RestController 註解來指示該控制器返回 JSON 響應。 此外,我們使用 @RequestBody 將傳入的 JSON 請求體綁定到 User 對象上。 如果驗證失敗,我們將返回一個 400 Bad Request 響應,其中包含 JSON 響應體中的錯誤消息。 否則,我們將返回一個 200 OK 響應,其中包含成功的消息。
4. 使用 Curl 進行測試
要使用 Curl 測試此 API,我們可以發送包含 User 對象數據的 JSON 請求體:
curl -X POST \
http://localhost:8080/api/users \
-H 'Content-Type: application/json' \
-d '{"name":"","email":""}'這應該返回一個 400 Bad Request 響應,包含一個 JSON 響應體,其中包含錯誤消息:
[
{
"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"
}
]如果發送一個有效的 User 對象,其中包含名稱和電子郵件,API 應該返回一個 200 OK 響應以及一個成功的消息:
curl -X POST \
http://localhost:8080/api/users \
-H 'Content-Type: application/json' \
-d '{"name":"John Doe","email":"[email protected]"}'因此,請求返回了一個成功的響應消息:
"User created successfully!"5. 驗證上下文
此外,在某些情況下,我們可能需要將額外的上下文傳遞給驗證器。 Spring 的 Validator 接口通過 validate(Object target, Errors errors, Object… validationHints) 方法支持驗證上下文。 因此,為了使用驗證上下文,我們可以通過調用 validate() 方法時將額外的對象作為驗證提示傳遞。
例如,我們想要根據特定場景驗證一個 User 對象:
public void validate(Object target, Errors errors, Object... validationHints) {
User user = (User) target;
if (validationHints.length > 0) {
if (validationHints[0] == "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
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
}
}在本示例中,UserValidator 會檢查 validationHints 數組以確定要使用的驗證場景。 讓我們更新 UserController 以使用 UserValidator 並結合 validationHints:
@PutMapping("/{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
return ResponseEntity.ok("User updated successfully!");
}現在,讓我們使用以下 curl 命令,同時將 name 和 email 字段都留空:
curl -X PUT \
http://localhost:8080/api/users/1 \
-H 'Content-Type: application/json' \
-d '{"name":"","email":""}'UserValidator 返回一個 400 Bad Request 響應,並附帶錯誤消息:
[
{
"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"
}
]如果只傳遞一個字段,例如 name 字段,則 UserValidator 允許更新繼續進行:
curl -X PUT \
http://localhost:8080/api/users/1 \
-H 'Content-Type: application/json' \
-d '{"name":"John Doe"}'響應是 200 OK 響應,表明更新已成功:
"User updated successfully!"6. 結論
在本文中,我們學習瞭如何使用 <em >Validator</em> 接口在基於 Spring 的應用程序中驗證對象。我們探討了 <em >Validator</em> 接口的兩個方法,supports() 和 validate(),以及如何實現自定義驗證器來驗證對象。