数据校验是软件工程中的关键环节,特别是在网络应用中,它确保了用户提交的数据符合预期的格式和约束条件,从而避免了潜在的安全风险和数据错误。服务端的数据校验尤为重要,因为它能有效防御客户端可能的恶意篡改,确保系统接收的数据安全可靠。
1.Bean Validation API简介
Bean Validation API,作为Java EE和Java SE的一部分,为Java对象的属性验证提供了一个标准化的解决方案。它的核心优势在于能够以一种声明式的方式定义属性约束,从而简化了数据验证的实现。
2. 介绍
- 注解驱动:Bean Validation API引入了一系列注解,如
@NotNull
、@Size
、@Email
等,可以直接应用于Java类的属性上,声明该属性应遵循的约束条件。 - 集成广泛:虽然它常与JPA结合使用,确保数据库实体在持久化前满足特定规则,但其实用范围远不止于此,适用于任何形式的Java应用程序。
3. 常见应用
- 数据输入验证:在Web应用程序中,通过表单输入的数据可以在后台使用Bean Validation进行验证,确保数据的完整性和正确性。
- 数据库实体验证:在使用JPA进行持久化操作时,可以确保实体对象在存储到数据库之前满足特定的约束条件。
- 业务逻辑验证:在业务逻辑中,确保传递的参数或对象满足特定的业务规则。
4. 代码示例
- 实体类:
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
public class User {
@NotNull(message = "名字不能为空")
@Size(min = 2, max = 30, message = "名字的长度为必须为2到30个字符之间")
private String name;
@NotNull(message = "邮箱不能为空")
@Email(message = "无效的邮箱格式")
private String email;
// getters and setters
}
- 测试代码
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import java.util.Set;
public class Main {
public static void main(String[] args) {
User user = new User();
user.setName("J");
user.setEmail("invalid-email");
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<User>> violations = validator.validate(user);
for (ConstraintViolation<User> violation : violations) {
System.out.println(violation.getMessage());
}
}
}
- 输出结果:
无效的邮箱格式
名字的长度为必须为2到30个字符之间
5. 常用注解
注解 | 说明 |
---|---|
@AssertFalse | 注解的元素必须是false 。 |
@AssertTrue | 注解的元素必须是true 。 |
@DecimalMax | 注解的元素必须是数字,其值必须小于或等于指定的最大值。 |
@DecimalMin | 注解的元素必须是数字,其值必须大于或等于指定的最小值。 |
@Digits | 注解的元素必须是可接受范围内的数字。 |
注解的元素必须是有效电子邮件地址。 | |
@Future | 注解的元素必须是将来的日期时间。 |
@FutureOrPresent | 注解的元素必须是当前或将来的日期时间。 |
@Max | 注解的元素必须是数字,其值必须小于或等于指定的最大值。 |
@Min | 注解的元素必须是数字,其值必须大于或等于指定的最小值。 |
@Negative | 注解的元素必须是严格的负数(即0 被视为无效值)。 |
@NegativeOrZero | 注解的元素必须是负数或0 。 |
@NotBlank | 注解的元素不能是null ,并且必须至少包含一个非空白字符。 |
@NotEmpty | 注解的元素不能是null 或空。 |
@NotNull | 注解的元素不能是null 。 |
@Null | 注解的元素必须是null 。 |
@Past | 注解的元素必须是过去的日期时间。 |
@PastOrPresent | 注解的元素必须是当前或过去的日期时间。 |
@Pattern | 注解的元素必须与指定的正则表达式匹配。 |
@Positive | 注解的元素必须是严格的正数(即0 被视为无效值)。 |
@PositiveOrZero | 注解的元素必须是正数或0 。 |
@Size | 注解的元素必须在指定的边界(包含)之间。 |
6. SpringBoot集成
- 步骤 1:定义实体类,在实体类的属性上添加约束条件(参考以上的通用注解)
@Data
class MyEntity {
@NotNull(message="用户信息不能为空")
@Size(min = 1, max = 100)
private String name;
}
- 步骤 2:在 Controller 方法的形参当中添加
@Valid
或者@Validated
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@PostMapping("/create")
public ResponseEntity<String> create(@Valid @RequestBody MyEntity myEntity) {
// 业务逻辑
return ResponseEntity.ok("Entity created");
}
}
- 步骤 3:发送 Http 请求,SpringMVC 会在方法执行之前进行参数的校验。
- 如果 Http 请求传递过来的参数不满足约束条件则控制器不会执行方法体,而是返回一个包含验证错误信息的响应。
- 在约束条件注解当中添加 message 属性可以在错误信息响应中添加自定义的错误信息。
7. 自定义检验格式
在实际开发中,Java 对象的属性可能存在特殊的格式要求。Bean Validation API 提供的标准校验注解有时无法满足这些特定需求。这种情况下,可以使用 @Pattern
注解,通过正则表达式自定义校验规则。例如,对于手机号码的校验,可以使用如下代码:
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
public class UserDTO {
@NotNull(message = "手机号码不能为空")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码格式不正确")
private String phoneNumber;
// Getters and Setters
}