不局限于controller的限制,可以在任何场景下,使用注解的方式对DTO进行参数校验,
由于spring-web-stater中已包含了 相关的依赖,如果是web工程,无需单独引入依赖。
使用注解标注在DTO的指定字段上,改字段必须满足注解所要求的属性,否则将无法通过校验。javax所提供的校验相关的注解有(只列举常用注解)
@NotNUll 参数不能为空 @Null 参数对象必须为空 @AsertFalse 断言为false @AsertTrue 断言为true @DecimalMax 验证对象是否小于等于指定的值,小数存在精度 @BigdecimelMin 验证对象是否大于指定的值,小数存在精度 @Min 验证对象是否大于指定的值 @Max 验证对象是都小于指定的值 @size 验证对象长度是否再指定的范围内(array,collection,map,string) @Pattera 正则表达式校验 @Email 邮箱校验
/** * 最大公里数 */ @NotNull(message = "最大公里数不能为空") @Min(value = 0, message = "最大里程取值范围[0~99]") @Max(value = 99, message = "最大里程取值范围[0~99]") private Long maxDistance; /** * 车型映射 */ @NotNull(message = "车型映射不能为空") private Integer truckMapper; /** * 价格系数 */ @NotNull(message = "价格系数不能为空", groups = {PriceDiscount.class}) @DecimalMin(value = "1.0", message = "价格系数不能小于1", groups = {PriceDiscount.class}) @DecimalMax(value = "20.0", message = "价格系数不能大于20", groups = {PriceDiscount.class}) @Digits(integer = 2, fraction = 1, message = "仅支持一位小数", groups = {PriceDiscount.class}) private java.lang.Float priceDiscount;
private static ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) .configure() //快速失败 .failFast(true) .buildValidatorFactory(); private static Validator validator = validatorFactory.getValidator();
使用配置好的validator对加了注解的DTO进行校验,默认的校验组为default 失败信息会返回成一个set集合
Set<ConstraintViolation<T>> set = validator.validate(object, Default.class); if (CollectionUtils.isEmpty(set)) { return YmmResult.succResult(); } String msg = "参数错误"; Iterator<ConstraintViolation<T>> it = set.iterator(); if (it.hasNext()) { msg = it.next().getMessage(); } return YmmResult.failResult(ErrorCodeEnum.PARAM_ERROR.getCode(), msg);
遍历这个错误信息集合的set就可以获取到全部的未通过校验的信息
(如果配置了失败快速返回,只会有一条失败信息)
很多时候我们的一个方法并不需要对DTO中的全部方法进行校验,只需要校验当前方法需要使用到的某些属性,这个时候就可以使用分组校验使代码更加灵活
定义分组
定义类或者接口用来指定分组,这里选择在类中定义接口,方便统一管理
public class ValidationGroup { public interface group1{ } public interface group2{ } }
字段指定校验组
字段上group指定教研组,只有当validator入参为该校验组时,才会对字段进行这个校验,否则,不会校验
@DecimalMax(value = "20", message = "price should not more than 20",groups = ValidationGroup.group1.class) @DecimalMin(value = "0", message = "price should not less than 0") private Float price; //校验 Set<ConstraintViolation<ValidationDto>> validate = validator.validate(build, ValidationGroup.group1.class);
校验组继承
validator中如果指定了校验组为group1,其他校验组的规则都不会生效(未指定校验组的为默认校验组default,也不会生效),如果想让group1具有default的验证规则,只需要指定接口group1继承default
public class ValidationGroup { public interface group1 extends Default{ } public interface group2{ } }