Spring Validation黑科技!5个数据校验工具,让参数校验效率飙升200%
Spring Validation集成了JSR-380)规范,提供了一系列开箱即用的校验注解。这些注解能够帮助开发者快速实现对数据的基本验证,确保输入数据符合预期。1. 在UserDTO类中,使用@NotNull@NotBlank@Email等注解对字段进行校验,这些注解能够快速实现对字段的基本验证。2. 在中,通过@Valid注解对请求参数进行验证,并通过获取验证结果。3.如果校验失败,提交自定
01 Bean Validation基础解:快速上手,高效验证
Spring Validation集成了JSR-380
(Bean Validation 2.0
)规范,提供了一系列开箱即用的校验注解。
这些注解能够帮助开发者快速实现对数据的基本验证,确保输入数据符合预期。
@Data
public class UserDTO {
@NotNull(message = "用户ID不能为空")
private Long id;
@NotBlank(message = "用户名不能为空")
@Size(min = 4, max = 20, message = "用户名长度必须在4到20个字符之间")
private String username;
@Email(message = "邮箱格式不正确")
private String email;
@Min(value = 18, message = "年龄必须大于或等于18")
@Max(value = 120, message = "年龄必须小于或等于120")
private Integer age;
@Past(message = "出生日期必须是过去的日期")
private LocalDate birthDate;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码格式不正确")
private String phoneNumber;
}
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity createUser(@RequestBody @Valid UserDTO userDTO,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new ValidationException(bindingResult);
}
return ResponseEntity.ok(userDTO);
}
}
注解:
1. 在UserDTO
类中,使用@NotNull
、@NotBlank
、@Email
等注解对字段进行校验,这些注解能够快速实现对字段的基本验证。
2. 在UserController
中,通过@Valid
注解对请求参数进行验证,并通过BindingResult
获取验证结果。
3.如果校验失败,提交自定义的ValidationException
异常,提示用户输入数据不符合要求。
最佳实践:
使用有意义的错误消息,保持一致的命名风格,避免在实体类上直接使用验证注解,而是在DTO对象上应用验证规则。
这样可以更好地分离关注点,提高代码的可维护性。
02定制约束验证器:满足特定业务需求,且灵活强大
Spring Validation允许开发者创建自定义约束,满足特定业务规则的验证需求。
通过自定义约束验证器,可以实现复杂的业务逻辑,确保数据符合特定的业务规则。
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueUsernameValidator.class)
public @interface UniqueUsername {
String message() default "用户名已存在";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {
private UserRepository userRepository;
@Override
public boolean isValid(String username, ConstraintValidatorContext context) {
if (username == null) {
return true;
}
return !userRepository.existsByUsername(username);
}
}
public class UserRegistrationDTO {
@NotBlank
@Size(min = 4, max = 20)
@UniqueUsername
private String username;
}
注解:
1.定义了一个@UniqueUsername
注解,用于验证用户名是否唯一。
2.实现了ConstraintValidator
接口,重写了isValid方法,通过调用userRepository.existsByUsername
方法来判断用户名是否已存在。
3.在UserRegistrationDTO
类中,使用@UniqueUsername
注释解对username
字段进行校验。
使用: 场景验证业务特定规则,如唯一性约束、密码复杂度、信用卡格式等。
通过自定义约束验证器,可以灵活地实现各种复杂的业务逻辑校验。
03分组验证:根据不同场景,灵活切换验证规则
分组验证允许根据不同场景应用不同的验证规则,例如创建和更新操作可能需要不同的验证逻辑。
通过分组验证,可以灵活切换验证规则,满足不同场景下的校验需求。
public interface ValidationGroups {
interface Create {}
interface Update {}
}
@Data
public class ProductDTO {
@Null(groups = ValidationGroups.Create.class, message = "创建产品时ID必须为空")
@NotNull(groups = ValidationGroups.Update.class, message = "更新产品时ID不能为空")
private Long id;
@NotBlank(groups = {ValidationGroups.Create.class, ValidationGroups.Update.class})
private String name;
@PositiveOrZero(groups = ValidationGroups.Create.class)
@Positive(groups = ValidationGroups.Update.class)
private BigDecimal price;
}
@RestController
@RequestMapping("/api/products")
public class ProductController {
@PostMapping
public ResponseEntity createProduct(
@RequestBody @Validated(ValidationGroups.Create.class) ProductDTO productDTO) {
return ResponseEntity.ok(productDTO);
}
@PutMapping("/{id}")
public ResponseEntity<ProductDTO> updateProduct(
@PathVariable Long id,
@RequestBody @Validated(ValidationGroups.Update.class) ProductDTO productDTO) {
return ResponseEntity.ok(productDTO);
}
}
注解:
1.定义了两个分组接口Create
和Update
,分别用于创建和更新操作的验证。
-
2. 在
ProductDTO
类中,通过groups属性指定不同字段在不同分组下的验证规则。 -
3. 在
ProductController
中,通过@Validated注解指定了使用不同接口方法的验证包。
提示:注意使用@Validated
注解而不是@Valid
,因为只有之前支持分组验证。
通过分组验证,可以灵活切换验证规则,满足不同场景下的校验需求。
04诉求验证:深入复杂对象结构,确保数据缺陷
请求验证允许验证复杂对象结构中的请求对象。
通过在需要级联验证的字段上添加@Valid
注解,可以确保验证深入到请求对象中,从而保证整个对象结构的数据完整性。
@Data
public class OrderDTO {
@NotNull
private Long id;
@NotNull
@Valid
private CustomerDTO customer;
@NotEmpty
@Valid
private List<OrderItemDTO> items;
}
@Data
public class CustomerDTO {
@NotNull
private Long id;
@NotBlank
private String name;
@Email
private String email;
@Valid
private AddressDTO address;
}
注解:
1.在OrderDTO
类中,customer
和items字段使用了@Valid
注解,表示对这些请求对象进行级联验证。
2.在CustomerDTO
类中,address
字段也使用了@Valid
注解,确保验证能够深入到层次的对象结构中。
关键点:
在需要级联验证的字段上添加@Valid
注释,确保验证深入到请求对象中。
通过请求验证,可以确保复杂对象结构中的每个字段都符合校验规则,从而保证数据的完整性。
05方法级别验证:服务层验证,增强代码健壮性
Spring Validation不仅可以用于控制器参数,还可以评估服务层的方法。
通过方法级别验证,可以确保服务层方法接收到的参数和返回的结果符合预期,增强代码的健壮性。
@Configuration
@EnableMethodValidation
public class ValidationConfig {
}
@Service
public class UserService {
@Validated
public User createUser(@Valid UserDTO userDTO) {
return new User();
}
@NotNull
public User findById(@Min(1) Long id) {
return new User();
}
@Validated(ValidationGroups.Update.class)
public void updateUser(@Valid UserDTO userDTO) {
}
}
注解:
1.在ValidationConfig
类中,通过@EnableMethodValidation
注解启用了方法级别验证。
2.在UserService
类中,通过@Validated
注解对方法参数和返回值进行校验。
3.在findById
方法中,使用@Min
注解对id参数进行校验,确保其值大于或等于1。
应用场景:
确保服务层方法接收到的参数和返回的结果符合预期,增强代码的健壮性。
通过方法级别验证,可以将校验逻辑从业务逻辑中分离出来,提高代码的可维护性和区分性。
更多推荐
所有评论(0)