Springboot3实体属性校验
Springboot3实体属性校验
1.使用 Jakarta Validation (原 javax.validation) 注解进行验证:
// 实体类
import jakarta.validation.constraints.*;
@Data
public class UserDTO {
@NotNull(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度必须在2-20之间")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 6, message = "密码长度不能小于6位")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
}
2.在 Controller 中使用 @Valid 或 @Validated 注解:
@RestController
@RequestMapping("/api")
public class UserController {
@PostMapping("/user")
public ResponseEntity<?> createUser(@Valid @RequestBody UserDTO userDTO) {
// 处理业务逻辑
return ResponseEntity.ok().build();
}
}
3.修改全局异常处理器,添加参数验证异常处理:
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理自定义异常
@ExceptionHandler(CustomException.class)
public ResponseEntity<Object> handleCustomException(CustomException ex) {
Map<String, Object> body = new HashMap<>();
body.put("status", 4001);
body.put("message", ex.getMessage());
return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
}
// 处理参数验证异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, Object> body = new HashMap<>();
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.toList());
body.put("status", 4002);
body.put("message", "参数验证失败");
body.put("errors", errors);
return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
}
}
4.在 pom.xml 中添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
5.常用的验证注解:
@NotNull // 不能为null
@NotEmpty // 不能为空,用于集合
@NotBlank // 不能为空,用于String,会去除前后空格
@Size // 长度或大小范围
@Min // 最小值
@Max // 最大值
@Email // 邮箱格式
@Pattern // 正则表达式
@Past // 必须是过去的日期
@Future // 必须是将来的日期
@Positive // 正数
@Negative // 负数
6.如果需要分组验证,可以这样做:
// 定义验证组
public interface Create {}
public interface Update {}
// 在实体类中使用组
public class UserDTO {
@NotNull(groups = {Create.class, Update.class})
private String username;
@NotNull(groups = Create.class)
private String password;
}
// 在Controller中指定组
@PostMapping("/user")
public ResponseEntity<?> createUser(@Validated(Create.class) @RequestBody UserDTO userDTO) {
// ...
}
使用这种方式的优点是:
代码简洁,易于维护
验证逻辑与业务逻辑分离
可以自定义错误消息
支持分组验证
可以通过全局异常处理统一处理验证错误
注意事项:
确保添加了validation依赖
记得在Controller方法参数上添加@Valid或@Validated注解
可以根据需要自定义错误消息
可以组合使用多个注解
对于复杂的验证逻辑,可以自定义验证注解
我来详细分类说明这些验证注解:
字符串相关的验证注解:
@NotBlank
只能用于String类型
判断字符串不能为null,并且去除首尾空格后长度必须大于0
@NotBlank(message = "名称不能为空")
private String name;
@Size
可用于String、Collection、Map、数组
检查字符串长度或集合大小是否在指定范围内
@Size(min = 2, max = 30, message = "名称长度必须在2-30之间")
private String name;
@Email
只能用于String类型
验证是否是合法的邮箱格式
@Email(message = "邮箱格式不正确")
private String email;
@Pattern
只能用于String类型
使用正则表达式进行验证
@Pattern(regexp = "^[0-9]{11}$", message = "手机号格式不正确")
private String phone;
数字相关的验证注解:
@Min
用于数字类型(整数或小数)
验证数字是否大于或等于指定的最小值
@Min(value = 0, message = "年龄不能小于0")
private Integer age;
@Max
用于数字类型(整数或小数)
验证数字是否小于或等于指定的最大值
@Max(value = 150, message = "年龄不能大于150")
private Integer age;
@Positive
用于数字类型
验证数字是否为正数(大于0)
@Positive(message = "数量必须为正数")
private Integer quantity;
@PositiveOrZero
用于数字类型
验证数字是否为正数或0
@PositiveOrZero(message = "数量必须大于或等于0")
private Integer quantity;
@Negative
用于数字类型
验证数字是否为负数(小于0)
@Negative(message = "温度必须为负数")
private Integer temperature;
@NegativeOrZero
用于数字类型
验证数字是否为负数或0
@NegativeOrZero(message = "温度必须小于或等于0")
private Integer temperature;
@DecimalMin
用于数字类型
验证数字是否大于或等于指定的最小值(可以指定是否包含边界值)
@DecimalMin(value = "0.1", message = "比例必须大于0.1")
private BigDecimal ratio;
@DecimalMax
用于数字类型
验证数字是否小于或等于指定的最大值(可以指定是否包含边界值)
@DecimalMax(value = "1.0", message = "比例必须小于1.0")
private BigDecimal ratio;
通用的验证注解:
@NotNull
可用于任何类型
验证属性值不能为null
@NotNull(message = "对象不能为null")
private Object obj;
@NotEmpty
可用于String、Collection、Map、数组
验证对象不能为null且不能为空(长度或大小必须大于0)
@NotEmpty(message = "列表不能为空")
private List<String> items;
实际使用示例:
@Data
public class UserDTO {
// 字符串验证
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度必须在2-20之间")
private String username;
// 数字验证
@Min(value = 0, message = "年龄不能小于0")
@Max(value = 150, message = "年龄不能大于150")
private Integer age;
// 邮箱验证
@Email(message = "邮箱格式不正确")
private String email;
// 手机号验证
@Pattern(regexp = "^[0-9]{11}$", message = "手机号格式不正确")
private String phone;
// 金额验证
@PositiveOrZero(message = "金额必须大于或等于0")
private BigDecimal amount;
}
这些注解可以组合使用,以实现更复杂的验证需求。同时,你也可以自定义错误消息,使用占位符来实现更灵活的提示信息。