前言
以下是关于 javax.validation.constraints(现为 jakarta bean validation)的详细说明,涵盖核心注解、使用场景、代码示例及最佳实践:
一、javax.validation.constraints 是什么?
- 作用:提供一组标准注解,用于对 java bean 的字段或方法参数进行数据校验(如非空、长度、范围等)。
- 规范演进:
- java ee 时期:包名为
javax.validation.constraints。 - jakarta ee 9+:包名迁移为
jakarta.validation.constraints(需注意依赖兼容性)。
- java ee 时期:包名为
二、核心注解列表及用法
1. 常用注解
| 注解 | 校验规则 | 支持类型 |
|---|---|---|
@notnull | 值不能为 null | 任意类型 |
@notblank | 字符串不能为空或纯空格 | string |
@notempty | 集合/数组/字符串不能为空(长度 > 0) | collection, string 等 |
@size(min, max) | 元素数量或字符串长度在指定范围内 | 集合、数组、字符串 |
@min(value) | 数值必须 ≥ 指定最小值 | 数值类型(int, long 等) |
@max(value) | 数值必须 ≤ 指定最大值 | 同上 |
@decimalmin(value) | 数值必须 ≥ 指定最小值(字符串形式,支持精度) | bigdecimal, string 等 |
@decimalmax(value) | 数值必须 ≤ 指定最大值(字符串形式,支持精度) | 同上 |
@digits(integer, fraction) | 数值整数部分最多 integer 位,小数部分最多 fraction 位 | 数值类型 |
@pattern(regexp) | 字符串必须匹配正则表达式 | string |
@email | 字符串必须是合法邮箱格式 | string |
@positive / @positiveorzero | 数值必须为正数或零 | 数值类型 |
@negative / @negativeorzero | 数值必须为负数或零 | 数值类型 |
@future / @futureorpresent | 日期必须在未来(或包含当前) | date, localdate 等 |
@past / @pastorpresent | 日期必须在过去(或包含当前) | 同上 |
2. 注解示例代码
public class user {
@notblank(message = "用户名不能为空")
private string username;
@email(message = "邮箱格式无效")
private string email;
@size(min = 6, max = 20, message = "密码长度需在6-20位之间")
private string password;
@min(value = 18, message = "年龄必须≥18岁")
@max(value = 100, message = "年龄必须≤100岁")
private integer age;
@pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式无效")
private string phone;
}三、集成到 spring boot 中的步骤
1. 添加依赖
<!-- spring boot 2.x 使用 javax.validation -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-validation</artifactid>
</dependency>
<!-- jakarta ee 9+ 使用 jakarta.validation -->
<dependency>
<groupid>jakarta.validation</groupid>
<artifactid>jakarta.validation-api</artifactid>
<version>3.0.2</version>
</dependency>2. 在 controller 中触发校验
使用 @valid 或 @validated 注解触发校验:
@postmapping("/users")
public responseentity<?> createuser(@requestbody @valid user user) {
// 校验通过后执行业务逻辑
return responseentity.ok("用户创建成功");
}3. 处理校验异常
通过 @exceptionhandler 捕获 methodargumentnotvalidexception:
@restcontrolleradvice
public class globalexceptionhandler {
@exceptionhandler(methodargumentnotvalidexception.class)
public responseentity<map<string, string>> handlevalidationexception(methodargumentnotvalidexception ex) {
map<string, string> errors = new hashmap<>();
ex.getbindingresult().getallerrors().foreach(error -> {
string fieldname = ((fielderror) error).getfield();
string errormessage = error.getdefaultmessage();
errors.put(fieldname, errormessage);
});
return responseentity.badrequest().body(errors);
}
}四、高级用法
1. 分组校验
通过分组接口实现不同场景下的差异化校验:
// 定义分组接口
public interface creategroup {}
public interface updategroup {}
public class user {
@notnull(groups = updategroup.class)
private long id;
@notblank(groups = {creategroup.class, updategroup.class})
private string name;
}
// 在 controller 中指定分组
@postmapping("/users")
public responseentity<?> createuser(@requestbody @validated(creategroup.class) user user) { ... }2. 自定义校验注解
实现自定义校验逻辑(如密码强度校验):
@target({field})
@retention(runtime)
@constraint(validatedby = passwordvalidator.class)
public @interface strongpassword {
string message() default "密码必须包含大小写字母和数字";
class<?>[] groups() default {};
class<? extends payload>[] payload() default {};
}
public class passwordvalidator implements constraintvalidator<strongpassword, string> {
@override
public boolean isvalid(string password, constraintvalidatorcontext context) {
return password.matches("^(?=.*[a-z])(?=.*[a-z])(?=.*\\d).+$");
}
}3. 级联校验
校验对象内的嵌套对象:
public class order {
@valid
private list<@valid product> products; // 校验每个 product 的字段
}五、校验失败的错误消息定制
1. 默认消息模板
每个注解的 message 属性支持占位符:
@size(min = 6, max = 20, message = "密码长度需在{min}-{max}位之间")
private string password;2. 国际化消息
在 messages.properties 或 validationmessages.properties 中定义:
user.email.invalid=邮箱格式无效
注解中使用:
@email(message = "{user.email.invalid}")
private string email;六、常见问题与解决方案
| 问题 | 解决方案 |
|---|---|
| 校验未生效 | 检查是否添加了 @valid 或 @validated 注解;确认依赖已正确引入 |
| 嵌套对象校验失败 | 在嵌套对象字段上添加 @valid 注解 |
| 分组校验不生效 | 在 @validated 注解中明确指定分组接口 |
| 自定义校验器未触发 | 确认 @constraint(validatedby = myvalidator.class) 并实现 constraintvalidator |
七、总结
- 核心价值:通过声明式注解简化数据校验逻辑,减少样板代码。
- 最佳实践:
- 优先使用标准注解,避免重复造轮子。
- 结合分组校验实现多场景复用。
- 统一处理校验异常,返回清晰的错误信息。
- 扩展性:通过自定义注解和校验器满足复杂业务需求。
到此这篇关于关于javax.validation.constraints超详细说明的文章就介绍到这了,更多相关javax.validation.constraints说明内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论