知識庫 / Spring RSS 訂閱

使用 Spring 驗證器接口進行驗證

Spring
HongKong
5
11:05 AM · Dec 06 ,2025

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 命令,同時將 nameemail 字段都留空:

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(),以及如何實現自定義驗證器來驗證對象。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.