01 依賴配置
在構建高效的校驗體系前,需先完善項目依賴配置。
以下是優化后的依賴示例:
<dependencies><!-- Web 依賴,提供 RESTful 接口支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 校驗核心依賴,整合 Hibernate Validator 實現 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
</dependencies>
注解:
- spring-boot-starter-web 依賴引入了 Spring MVC 組件,為構建 Web 應用提供基礎支持
- spring-boot-starter-validation 依賴整合了 Hibernate Validator 實現,提供 JSR 380 校驗規范支持
02 校驗注解體系構建
構建完善的校驗注解體系是實現數據校驗的基礎。
以下是企業級校驗注解應用示例:
import javax.validation.constraints.*;
import java.time.LocalDate;public class UserRegistrationRequest {// 用戶名校驗:非空且長度在 4-20 位之間@NotBlank(message = "用戶名不能為空")@Size(min = 4, max = 20, message = "用戶名長度需在 4-20 位之間")private String username;// 郵箱校驗:非空且符合郵箱格式@NotBlank(message = "郵箱不能為空")@Email(message = "郵箱格式不正確")private String email;// 密碼校驗:非空且長度不少于 8 位@NotBlank(message = "密碼不能為空")@Size(min = 8, message = "密碼長度至少為 8 位")private String password;// 年齡校驗:必須大于 0 且小于 150@Min(value = 1, message = "年齡必須大于 0")@Max(value = 150, message = "年齡不能超過 150")private Integer age;// 出生日期校驗:不能晚于當前日期@PastOrPresent(message = "出生日期不能晚于當前日期")private LocalDate birthDate;// 協議同意校驗:必須為 true@NotNull(message = "必須同意服務條款")private Boolean termsAccepted;
}
注解:
- 使用組合注解實現多維度校驗,如 @NotBlank + @Size 實現既校驗非空又校驗長度的雙重校驗
- 通過明確的錯誤提示信息,提升系統友好性,便于用戶定位問題
- 日期類型使用 @PastOrPresent 校驗,避免接收未來日期的非法輸入
03 控制器校驗集成
在控制器層面集成校驗邏輯,確保所有入參經過嚴格校驗:
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import javax.validation.Valid;@Validated // 啟用方法參數校驗
@RestController
@RequestMapping("/api/users")
public class UserController {@PostMapping("/register")public ResponseEntity registerUser(@Valid @RequestBody UserRegistrationRequest request) {// 業務邏輯處理return ResponseEntity.ok("用戶注冊成功");}@GetMapping("/{id}")public ResponseEntity getUserById(@PathVariable Long id) {// 用戶查詢邏輯return ResponseEntity.ok(new User(id, "示例用戶"));}
}
注解:
-
@Validated 注解啟用控制器方法參數校驗,配合 @Valid 對請求體進行深度校驗
-
@RequestBody 結合校驗注解,實現復雜對象的自動綁定與校驗
-
通過明確的 HTTP 狀態碼和響應消息,提供標準化的接口反饋
04 全局異常處理機制
構建完善的全局異常處理機制,統一管理校驗異常:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity handleValidationExceptions(MethodArgumentNotValidException ex) {Map<String, String> errors = new HashMap<>();ex.getBindingResult().getFieldErrors().forEach(error -> {errors.put(error.getField(), error.getDefaultMessage());});return ResponseEntity.badRequest().body(errors);}@ExceptionHandler(Exception.class)public ResponseEntity handleGeneralException(Exception ex) {return ResponseEntity.internalServerError().body("系統內部錯誤");}
}
注解:
- 通過 @RestControllerAdvice 實現全局異常處理,集中管理各類異常
- 針對校驗異常提取字段級錯誤信息,返回結構化的錯誤響應
- 提供默認異常處理方法,確保所有未被捕獲的異常都能得到妥善處理
05 分組校驗實現
在復雜業務場景中,通過分組校驗實現條件校驗邏輯:
// 定義校驗分組接口
public interface CreateGroup {}
public interface UpdateGroup {}// 應用分組校驗的 DTO 類
public class UserDTO {@NotBlank(groups = CreateGroup.class, message = "創建時用戶名必填")@Size(groups = CreateGroup.class, min = 4, message = "用戶名長度至少為 4")private String username;@Email(groups = {CreateGroup.class, UpdateGroup.class}, message = "郵箱格式不正確")private String email;// Getter 和 Setter 方法
}
// 控制器方法應用分組校驗
@PostMapping("/users")
public ResponseEntity createUser(@Validated({CreateGroup.class}) UserDTO userDTO) {// 創建用戶邏輯return ResponseEntity.ok("用戶創建成功");
}@PutMapping("/users/{id}")
public ResponseEntity updateUser(@Validated({UpdateGroup.class}) UserDTO userDTO) {// 更新用戶邏輯return ResponseEntity.ok("用戶更新成功");
}
注解:
-
通過定義接口實現校驗分組,靈活控制不同場景下的校驗規則
-
在 DTO 類中指定各字段所屬的校驗分組,實現條件校驗
-
控制器方法通過指定校驗分組,精確控制校驗邏輯的觸發場景
06 嵌套對象校驗
處理復雜對象嵌套場景下的校驗需求:
// 嵌套對象校驗示例
public class Order {@NotBlank(message = "訂單號不能為空")private String orderId;@DecimalMin(value = "0.01", message = "訂單金額必須大于 0.01")private BigDecimal amount;// 嵌套 Customer 對象,啟用深度校驗@Validprivate Customer customer;
}public class Customer {@NotBlank(message = "客戶名稱不能為空")private String name;@Email(message = "郵箱格式不正確")private String email;// 嵌套 Address 對象,繼續深度校驗@Validprivate Address address;
}public class Address {@NotBlank(message = "地址不能為空")private String street;@NotBlank(message = "城市不能為空")private String city;
}
// 控制器方法應用嵌套校驗
@PostMapping("/orders")
public ResponseEntity createOrder(@Valid @RequestBody Order order) {// 訂單創建邏輯return ResponseEntity.ok("訂單創建成功");
}
注解:
- 使用 @Valid 注解啟用嵌套對象的深度校驗,支持多層對象嵌套
- 校驗規則沿用對象關系,自動繼承父對象的校驗上下文
- 全局異常處理器自動捕獲嵌套校驗錯誤,返回詳細的錯誤路徑信息
07 自定義校驗注解開發
針對特殊業務場景開發自定義校驗注解:
// 自定義注解定義
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface ValidPhoneNumber {String message() default "手機號格式不正確";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}// 自定義校驗實現
public class PhoneValidator implements ConstraintValidator<ValidPhoneNumber, String> {private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";@Overridepublic void initialize(ValidPhoneNumber constraintAnnotation) {// 初始化邏輯}@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {if (value == null || value.trim().isEmpty()) {return true; // 空值不校驗}return Pattern.matches(PHONE_REGEX, value);}
}
// 自定義注解應用示例
public class ContactInfo {@ValidPhoneNumberprivate String phone;// Getter 和 Setter 方法
}
注解:
- 通過 @Constraint 注解指定校驗器實現類,完成自定義校驗注解開發
- 校驗器實現類需繼承 ConstraintValidator,重寫 isValid 方法定義校驗邏輯
- 自定義注解可應用于字段或參數,與內置注解使用方式一致