這是一個或許對你有用的社群
《專案實戰(影片)》:從書中學,往事上“練” 《網際網路高頻面試題》:面朝簡歷學習,春暖花開 《架構 x 系統設計》:摧枯拉朽,掌控面試高頻場景題 《精進 Java 學習指南》:系統學習,網際網路主流技術棧 《必讀 Java 原始碼專欄》:知其然,知其所以然
這是一個或許對你有用的開源專案
國產 Star 破 10w+ 的開源專案,前端包括管理後臺 + 微信小程式,後端支援單體和微服務架構。功能涵蓋 RBAC 許可權、SaaS 多租戶、資料許可權、商城、支付、工作流、大屏報表、微信公眾號、ERP、CRM、AI 大模型等等功能:
Boot 多模組架構:https://gitee.com/zhijiantianya/ruoyi-vue-pro Cloud 微服務架構:https://gitee.com/zhijiantianya/yudao-cloud 影片教程:https://doc.iocoder.cn 【國內首批】支援 JDK 17/21 + SpringBoot 3.3、JDK 8/11 + Spring Boot 2.7 雙版本
-
使用者名稱不能為空,長度在 3 到 20 個字元之間; -
密碼不能為空,長度至少為 8 個字元; -
年齡必須是正整數,不能超過 120; -
郵箱必須符合標準格式。
if
就完事了。一、傳統引數校驗的問題
@RestController
@RequestMapping
(
"/api/users"
)
publicclassUserController
{
@PostMapping
(
"/register"
)
public ResponseEntity<String> register(@RequestBody Map<String, Object> request)
{
String username = (String) request.get(
"username"
);
if
(username ==
null
|| username.length() <
3
|| username.length() >
20
) {
return
ResponseEntity.badRequest().body(
"使用者名稱不能為空,且長度必須在3到20之間"
);
}
String password = (String) request.get(
"password"
);
if
(password ==
null
|| password.length() <
8
) {
return
ResponseEntity.badRequest().body(
"密碼不能為空,且長度至少為8個字元"
);
}
Integer age = (Integer) request.get(
"age"
);
if
(age ==
null
|| age <=
0
|| age >
120
) {
return
ResponseEntity.badRequest().body(
"年齡必須是正整數,且不能超過120"
);
}
return
ResponseEntity.ok(
"註冊成功!"
);
}
}
-
程式碼冗餘 :校驗邏輯散落在 Controller 裡,寫起來麻煩,後期維護更是災難。 -
重複勞動 :類似的校驗邏輯可能會出現在多個接口裡,導致程式碼重複度極高。 -
使用者體驗差 :返回的錯誤資訊不統一、不規範,前端開發還得猜使用者輸入到底哪兒錯了。 -
擴充套件性差 :萬一某天需要加新的校驗規則,你可能要到處改程式碼。
基於 Spring Boot + MyBatis Plus + Vue & Element 實現的後臺管理系統 + 使用者小程式,支援 RBAC 動態許可權、多租戶、資料許可權、工作流、三方登入、支付、簡訊、商城等功能
專案地址:https://github.com/YunaiV/ruoyi-vue-pro 影片教程:https://doc.iocoder.cn/video/
二、Spring Boot 的引數校驗機制
1. 使用註解進行引數校驗
@Data
publicclassUserRegistrationRequest
{
@NotNull
(message =
"使用者名稱不能為空"
)
@Size
(min =
3
, max =
20
, message =
"使用者名稱長度必須在3到20之間"
)
private
String username;
@NotNull
(message =
"密碼不能為空"
)
@Size
(min =
8
, message =
"密碼長度至少為8個字元"
)
private
String password;
@NotNull
(message =
"年齡不能為空"
)
@Min
(value =
1
, message =
"年齡必須是正整數"
)
@Max
(value =
120
, message =
"年齡不能超過120"
)
private
Integer age;
@Email
(message =
"郵箱格式不正確"
)
private
String email;
}
-
@NotNull
:欄位不能為空; -
@Size
:限制字串長度; -
@Min
和@Max
:限制數值範圍; -
@Email
:校驗郵箱格式。
@RestController
@RequestMapping
(
"/api/users"
)
publicclassUserController
{
@PostMapping
(
"/register"
)
public ResponseEntity<String> register(@Valid @RequestBody UserRegistrationRequest request)
{
return
ResponseEntity.ok(
"註冊成功!"
);
}
}
@Valid
註解,它的作用是告訴 Spring:對請求引數進行校驗 。2. 統一處理校驗錯誤
MethodArgumentNotValidException
異常。預設情況下,這個異常返回的資訊不太友好,可能是這樣的:
{
"timestamp"
:
"2024-01-01T12:00:00.000+00:00"
,
"status"
:
400
,
"error"
:
"Bad Request"
,
"message"
:
"Validation failed for object='userRegistrationRequest'. Error count: 2"
,
"path"
:
"/api/users/register"
}
@RestControllerAdvice
publicclassGlobalExceptionHandler
{
@ExceptionHandler
(MethodArgumentNotValidException
.
class
)
publicResponseEntity
<
Map
<
String
,
String
>>
handleValidationException
(
MethodArgumentNotValidExceptionex
)
{
Map<String, String> errors =
new
HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error -> {
errors.put(error.getField(), error.getDefaultMessage());
});
return
ResponseEntity.badRequest().body(errors);
}
}
{
"username"
:
"使用者名稱長度必須在3到20之間"
,
"password"
:
"密碼不能為空"
}
基於 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的後臺管理系統 + 使用者小程式,支援 RBAC 動態許可權、多租戶、資料許可權、工作流、三方登入、支付、簡訊、商城等功能
專案地址:https://github.com/YunaiV/yudao-cloud 影片教程:https://doc.iocoder.cn/video/
三、應對複雜場景的高階技巧
1. 分組校驗
-
註冊介面要求 username
和password
是必填項; -
更新介面只需要校驗 email
和age
。
定義校驗分組
publicinterfaceRegisterGroup
{}
publicinterfaceUpdateGroup
{}
在欄位上指定分組
publicclassUserRequest
{
@NotNull
(groups = RegisterGroup
.class, message
=
"使用者名稱不能為空"
)
@Size
(min =
3
, max =
20
, groups = RegisterGroup
.class, message
=
"使用者名稱長度必須在3到20之間"
)
private
String username;
@NotNull
(groups = RegisterGroup
.class, message
=
"密碼不能為空"
)
private
String password;
@Email
(groups = UpdateGroup
.class, message
=
"郵箱格式不正確"
)
private
String email;
@Min
(value =
1
, groups = UpdateGroup
.class, message
=
"年齡必須是正整數"
)
private
Integer age;
}
在 Controller 中指定分組
@RestController
@RequestMapping
(
"/api/users"
)
publicclassUserController
{
@PostMapping
(
"/register"
)
public ResponseEntity<String> register(@Validated(RegisterGroup.class) @RequestBody UserRequest request)
{
return
ResponseEntity.ok(
"註冊成功!"
);
}
@PutMapping
(
"/update"
)
public ResponseEntity<String> update(@Validated(UpdateGroup.class) @RequestBody UserRequest request)
{
return
ResponseEntity.ok(
"更新成功!"
);
}
}
2. 自定義校驗註解
定義註解
@Documented
@Constraint
(validatedBy = PhoneValidator
.
class
)
@
Target
(
{ElementType.FIELD})
@Retention
(RetentionPolicy.RUNTIME)
public@interface
ValidPhone {
String message()default "手機號格式不正確"
;
Class<?>[] groups()
default
{};
Class<? extends Payload>[] payload()
default
{};
}
實現校驗邏輯
publicclassPhoneValidatorimplementsConstraintValidator<ValidPhone, String>
{
privatestaticfinal
String PHONE_REGEX =
"^1[3-9]\\d{9}$"
;
@Override
publicbooleanisValid(String value, ConstraintValidatorContext context)
{
return
value !=
null
&& value.matches(PHONE_REGEX);
}
}
使用自定義註解
publicclassUserRequest
{
@ValidPhone
private
String phone;
}
四、總結
-
註解優先:能用註解解決的校驗,就不要手寫邏輯程式碼。 -
分離校驗邏輯:引數校驗應該集中在 DTO 層,避免散落在業務程式碼中。 -
全域性統一異常處理:確保錯誤資訊規範化、友好化。 -
合理使用分組校驗:根據介面需求靈活調整校驗規則。 -
覆蓋邊界條件:透過單元測試驗證校驗邏輯,確保沒有漏網之魚。





