Spring Boot 參數校驗全指南
在 Web 開發中,參數校驗是保障接口安全性和數據合法性的關鍵環節。手動編寫校驗邏輯不僅繁瑣,還容易遺漏邊界情況。Spring Boot 整合了 validation
工具,提供了一套簡潔高效的參數校驗方案,可快速實現對簡單數據類型、對象類型的校驗,并支持自定義異常處理。
一、參數校驗入門:簡單數據類型校驗
1. 引入依賴
Spring Boot 提供了 spring-boot-starter-validation
起步依賴,內置了參數校驗所需的核心組件:
<!-- 參數校驗依賴 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2. 開啟參數校驗
在控制器類上添加 @Validated
注解,開啟參數校驗功能:
@Validated // 開啟參數校驗
@Controller
public class TestController {// 接口方法...
}
3. 常用校驗注解
對簡單數據類型(如字符串、數字)的校驗,可直接在方法參數上添加校驗注解。常用注解如下:
注解 | 作用 | 示例 |
---|---|---|
@NotBlank | 字符串不為 null 且去除空格后不為空串 | @NotBlank String username |
@NotNull | 對象不為 null(適用于包裝類) | @NotNull Integer age |
@NotEmpty | 集合不為 null 且不為空 | @NotEmpty List<String> ids |
@Min | 數字最小值 | @Min(0) Integer score |
@Max | 數字最大值 | @Max(150) Integer age |
@Email | 字符串符合郵箱格式 | @Email String email |
@Length | 字符串長度在指定范圍內 | @Length(min=2, max=10) String name |
4. 簡單類型校驗示例
@Validated
@Controller
public class TestController {@RequestMapping("/user")@ResponseBodypublic String addUser(@NotBlank(message = "用戶名不能為空") String username, // 非空校驗@NotNull(message = "年齡不能為空") @Min(0) @Max(150) Integer age, // 非空+范圍校驗@Email(message = "郵箱格式不正確") String email // 格式校驗) {return "參數校驗通過:" + username + ", " + age + ", " + email;}
}
message
屬性用于自定義校驗失敗時的提示信息。- 當參數不符合校驗規則時,會拋出
ConstraintViolationException
異常。
二、異常處理:統一響應錯誤信息
參數校驗失敗后,Spring Boot 會默認拋出異常并返回 400 錯誤,但默認的錯誤信息不夠友好。我們可以通過以下兩種方式統一處理校驗異常:
1. 自定義錯誤頁面(適用于前后端不分離)
Spring Boot 會自動跳轉至 src/main/resources/templates/error.html
頁面,可在該頁面展示友好的錯誤提示:
<!-- error.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>錯誤提示</title>
</head>
<body><h1>參數錯誤</h1><p>請檢查輸入的參數是否符合要求</p>
</body>
</html>
2. 全局異常處理器(適用于前后端分離)
通過 @ControllerAdvice
定義全局異常處理器,捕獲校驗異常并返回 JSON 格式的錯誤信息:
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {// 處理簡單類型參數校驗異常@ExceptionHandler(ConstraintViolationException.class)public Map<String, String> handleConstraintViolationException(ConstraintViolationException e) {Map<String, String> errorMap = new HashMap<>();// 獲取所有校驗失敗的信息e.getConstraintViolations().forEach(violation -> {String field = violation.getPropertyPath().toString(); // 參數名String message = violation.getMessage(); // 錯誤信息errorMap.put(field, message);});return errorMap;}
}
當參數校驗失敗時,會返回類似以下的 JSON 響應:
{"username": "用戶名不能為空","email": "郵箱格式不正確"
}
三、對象類型參數校驗
對于復雜業務場景,接口通常接收對象類型的參數(如用戶注冊信息、訂單信息)。此時需對對象的每個屬性進行校驗,步驟如下:
1. 定義實體類并添加校驗注解
在實體類的字段上添加校驗注解,指定校驗規則和錯誤提示:
public class User {@NotNull(message = "ID不能為空")private Integer id;@NotBlank(message = "姓名不能為空")@Length(min = 2, max = 10, message = "姓名長度必須在2-10之間")private String name;@NotNull(message = "年齡不能為空")@Min(value = 0, message = "年齡不能為負數")@Max(value = 150, message = "年齡不能超過150")private Integer age;// getter + setter(必須存在,否則校驗不生效)
}
2. 在控制器中校驗對象
在控制器方法的對象參數前添加 @Validated
注解,并通過 BindingResult
捕獲校驗結果:
@Controller
public class UserController {@RequestMapping("/addUser")@ResponseBodypublic String addUser(@Validated User user, // 開啟對象校驗BindingResult result // 用于接收校驗結果) {// 判斷是否有校驗失敗if (result.hasErrors()) {// 收集所有錯誤信息StringBuilder errorMsg = new StringBuilder();result.getAllErrors().forEach(error -> {FieldError fieldError = (FieldError) error;errorMsg.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append("; ");});return "參數錯誤:" + errorMsg.toString();}// 校驗通過,處理業務邏輯return "用戶添加成功:" + user.getName();}
}
@Validated
用于開啟對象的屬性校驗。BindingResult
必須緊跟在被校驗對象之后,用于接收校驗結果,避免異常直接拋出。
四、常見問題與最佳實踐
1. 校驗注解不生效?
- 確保已添加
spring-boot-starter-validation
依賴。 - 控制器類上是否添加
@Validated
注解(簡單類型校驗必需)。 - 對象類型校驗時,是否在參數前添加
@Validated
注解,且實體類有 getter/setter 方法。
2. 如何自定義校驗規則?
除了內置注解,還可通過 @Pattern
注解自定義正則校驗,例如校驗手機號:
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手機號格式不正確")
private String phone;
3. 全局異常處理器的優勢
使用 @ControllerAdvice
定義全局異常處理器,可統一處理所有校驗異常,避免在每個接口中重復編寫錯誤處理邏輯,提高代碼復用性。
總結
Spring Boot 的參數校驗機制通過注解化的方式,極大簡化了數據合法性校驗的實現。本文介紹了簡單類型、對象類型的校驗方法,以及異常處理方案,涵蓋了從基礎到實戰的核心場景。合理使用參數校驗,不僅能減少手動校驗代碼,還能提高接口的健壯性和安全性。