前言:参照springboot使用hibernate validator校验;文中标注深蓝色的地方,需要特殊对比参照。
一.准备
假定已经能正常使用spring-cloud框架
二.使用hibernate validator提供的校验注解
i.在Dto中给字段加注解
@NotBlank(message = "联系人电话为空") private String phone;
ii.定义校验配置
@Configuration public class ValidatorConfig { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor(); /*设置validator模式为快速失败返回*/ postProcessor.setValidator(validator()); return postProcessor; } @Bean public Validator validator(){ ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ) .configure() .addProperty( "hibernate.validator.fail_fast", "true" )//true--发现校验不过,立即返回,不在进行后续校验;false--全部校验完毕再返回 .buildValidatorFactory(); Validator validator = validatorFactory.getValidator(); return validator; } }
iii.使用现场,需要校验的参数前,增加@Validated注解, BindingResult result紧随要校验的参数后
@RequestMapping("saveAddress")
public Resp saveAddress(@RequestBody @Validated BuyAddressDto buyAddressDto, BindingResult result){
if(result.hasErrors()){
System.out.println(result.getAllErrors().get(0).getDefaultMessage());
}
}
如果需要全局统一处理,校验不过,则需要在方法定义时,除去 , BindingResult result,定义该类处理拦截器
@ControllerAdvice @Component public class ValidatorExceptHandler { @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody public Resp handle(MethodArgumentNotValidException exception) { String message = exception.getBindingResult().getAllErrors().get(0).getDefaultMessage(); return new Resp(BaseError.NOT_ENOUGH_PARAMS, message); } }
iv.控制校验字段顺序的手段
定义分组:
public interface GroupA {
}
public interface GroupB {
}
@GroupSequence({GroupA.class, GroupB.class, Default.class})
public interface GroupOrder {
}
字段校验注解中添加分组归属
@Money(message = "你发的是钱吗",groups = {GroupA.class}) private Double money; private String name; @NotBlank(message = "联系人电话为空",groups = {GroupB.class}) private String phone;
使用现场,增加校验分组支持,效果自现
@ResponseBody @RequestMapping("saveAddress") public Resp saveAddress(@RequestBody @Validated({GroupOrder.class}) BuyAddress buyAddress)
三.自定义校验注解兼容
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MoneyValidator.class)
public @interface Money {
String message() default"不是金额形式";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class MoneyValidator implements ConstraintValidator<Money, Double> {
private String moneyReg = "^\\d+(\\.\\d{1,2})?$";//表示金额的正则表达式
private Pattern moneyPattern = Pattern.compile(moneyReg);
public MoneyValidator() {}
public void initialize(Money money) {
}
public boolean isValid(Double value, ConstraintValidatorContext arg1) {
if (value == null)
return true;
return moneyPattern.matcher(value.toString()).matches();
}
}
自定义注解,使用方式也是一样的。