Java写后台服务的时候,经常需要对前台传过来的参数做校验,如果自己写这些校验,参数少还可以,但如果参数太多了的话就比较麻烦了,会在某种程度上影响开发效率。使用hibernate-validator校验数据,可以比较方便的解决这个问题。
现在我有一个实体类User,这个类有username、password等属性,在用户注册的时候,我希望username和password都必须要有值,否则,不让执行注册业务。
public class User {
private String id;
private String username;
private String password;
// 省略get、set
}
这个时候,我们可以在username和password属性上面添加@NotBlack注解:
@NotBlank
private String username;
@NotBlank
private String password;
@NotBlack在org.hibernate.validator.constraints包里面,使用它注解的字段不能为空。这个时候往往还是不够的,在controller层中我们还需要配套使用@Valid注解以使校验工作正常运行:
@PostMapping("user")
public User create(@Valid @RequestBody User user) {
System.out.println(user.getId());
System.out.println(user.getUsername());
System.out.println(user.getPassword());
System.out.println(user.getBirthday());
user.setId("1");
return user;
}
这样,如果前台传过来的数据中,username和password中的任一项为空的话,都不能正常进入到create逻辑中,前台调用的时候会直接返回400状态码。
这个时候需要注意的是,如果传过来的数据不符合规定的话,代码是不会执行到create方法中去的,如果业务需要进入到create方法中做些log等记录时,可以使用BindingResult:
@PostMapping("user")
public User create(@Valid @RequestBody User user, BindingResult errors) {
if (errors.hasErrors()) {
errors.getAllErrors().stream().forEach(e -> System.out.println(e.getDefaultMessage()));
return null;
}
System.out.println(user.getId());
System.out.println(user.getUsername());
System.out.println(user.getPassword());
System.out.println(user.getBirthday());
user.setId("1");
return user;
}
这样,逻辑会进入到方法内,这时就可以进行一些业务的操作了。
常见的校验注解有:
在使用注解的时候,可以使用message说明错误原因:
@NotBlank(message="用户名不能为空")
private String username;
以上注解是一些逻辑比较简单的注解,在实际开发中校验逻辑往往比较复杂,这个时候我们可能需要写一些自己的校验逻辑了,下面展示一下自己写校验逻辑的步骤。
首先写一个注解,这个注解主要用来标注在要校验的字段上的:
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyValidatorExecute.class)
public @interface MyValidator {
String message();
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
注意其中的:@Constraint(validatedBy = MyValidatorExecute.class),@Constraint注解是javax.validation包下的标准注解,它主要声明了@MyValidator这个注解的校验逻辑要通过MyValidatorExecute来执行,被@Constraint修饰的注解必须要有message、groups、payload三个属性,具体可以仿造@NotBlank等注解。下面接着写MyValidatorExecute,校验逻辑主要在这个类中,他必须实现ConstraintValidator:
public class MyValidatorExecute implements ConstraintValidator<MyValidator, Object>{
@Override
public void initialize(MyValidator arg0) {
}
@Override
public boolean isValid(Object arg0, ConstraintValidatorContext arg1) {
return false;
}
}
ConstraintValidator<A,T>中,A表示你要验证的注解是什么,这里我们要验证的注解是MyValidator;T表示你要验证的那个东西的类型是什么,这里为了方便,我们直接指定为Object类型了。initialize是这个校验器初始化的方法,isValid是主要的校验方法,当这个方法返回true时表示校验通过,否则校验不通过。需要特别声明的是,在MyValidatorExecute这个类中,我们可以直接通过@Autowired引入spring容器管理的任意组件,这个spring会自动把实现了ConstraintValidator的类纳入到它的管理之中。
以上就是hibernate-validator的常用使用了。