文章目录
# 前言
- jdk javax.validation包下的接口
- hibernate validation实现类
- spring-boot validation实现类
一、jdk java.validation?
就是一个规范, 所有实现类必须是线程安全的, 提供以下注解, 但并不提供实现
提供实现接口
public interface ConstraintValidator<A extends Annotation, T> {
二、hibernate validation
实现了jdk Validator接口以及ExecutableValidator接口
public class ValidatorImpl implements Validator, ExecutableValidator {
新增以下注解:
提供接口实现:
三 spring-boot-starter-validation
定义Validator以及SmartValidator接口, 添加了hibernate的包, 提供@Validated支持spring环境,支持验证组的规范, 支持在spring mvc的环境中使用,提供了一系列的工厂类, 以及适配器;
四 使用
一 基本使用:
代码如下(示例):
@RestController
public class UserController {
@RequestMapping
public Response<Object> login(@Validated UserLogin user) {
return Response.builder().code(200).message("ok").data("ok").build();
}
}
@Data
public class UserLogin {
@NotBlank
@Size(max = 10)
private String username;
private String password;
}
二 自定义注解
代码如下(示例):
@Documented
@Constraint(validatedBy = {GenderValidator.class})
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface GenderValidation {
String message() default "性别取值范围不对";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class GenderValidator implements ConstraintValidator<GenderValidation, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return false;
}
return value.equals("男") || value.equals("女");
}
@Override
public void initialize(GenderValidation constraintAnnotation) {
}
}
@Data
public class UserLogin {
@NotBlank
@Size(max = 10)
private String username;
private String password;
// 添加注解, 用以启用自定义注解校验
@GenderValidation
private String gender;
}
三 自定义Validator
此方式为实现对对象的校验
代码如下(示例):
实现Validator:
@Configuration
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return clazz.equals(UserLogin2.class);
}
@Override
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmpty(errors, "username", "username.empty");
ValidationUtils.rejectIfEmpty(errors, "password", "password.empty");
UserLogin2 userLogin2 = (UserLogin2) target;
System.out.println(userLogin2);
}
}
@RestController
public class UserController extends ValidationInitController {
@Autowired
private UserValidator userValidator;
@InitBinder
public void initBinder(WebDataBinder dataBinder) {
dataBinder.setValidator(userValidator);
}
@RequestMapping("/login")
public Response<Object> login(@Validated @RequestBody UserLogin2 user) {
return Response.builder().code(200).message("ok").data("ok").build();
}
}
@Data
@ToString
public class UserLogin2 {
private String username;
private String password;
}
四 使用编程方式启动校验(hibernate手动)
代码如下(示例):
// 配置到spring中, 或者采用其它方式也可以
// 直接使用hibernate提供的验证实现
@Configuration
public class HibernateValidationConfig {
@Bean
public Validator init() {
HibernateValidatorConfiguration configuration = Validation.byProvider(HibernateValidator.class).configure();
// 快速失败模式, 检查到第一个失败就返回
ValidatorFactory factory = configuration.failFast(true).buildValidatorFactory();
return factory.getValidator();
}
}
@RestController
public class UserController extends ValidationInitController {
@Qualifier("init")
@Autowired
private Validator validator;
@RequestMapping
public Response<Object> login(UserLogin3 user) {
Set<ConstraintViolation<UserLogin3>> validate = validator.validate(user);
// 如果验证失败, 只会有一条数据
for (ConstraintViolation<UserLogin3> userLoginConstraintViolation : validate) {
String message = userLoginConstraintViolation.getMessage();
System.out.println(message);
}
return Response.builder().code(200).message("ok").data("ok").build();
}
}
五 分组验证
代码如下(示例):
@Data
@ToString
public class UserLogin4 {
@NotNull(groups = {UserUpdate.class}, message = "userId not null")
private Integer userId;
private String username;
private String password;
public interface UserInsert extends Default {
}
public interface UserUpdate extends Default {
}
}
@RestController
public class UserController {
@RequestMapping("/user/insert")
public Response<Object> userInsert(@Validated(UserLogin4.UserInsert.class) @RequestBody UserLogin4 user) {
return Response.builder().code(200).message("ok").data("ok").build();
}
@RequestMapping("/user/update")
public Response<Object> userUpdate(@Validated(UserLogin4.UserUpdate.class) @RequestBody UserLogin4 user) {
return Response.builder().code(200).message("ok").data("ok").build();
}
}
总结
至于返回码等参考spring设置统一返回处理类, 对异常处理即可, 这里就不贴出来了