服务端数据源验证采用遵循JSR 303 – Bean Validation 规范,Bean Validation 是一个运行时的数据验证框架,为 JavaBean 验证定义了相应的元数据模型和 API。
一个简单的例子如下:
/*** 系统参数*/@Data@ApiModel(description = "系统参数")public class SysParam implements Serializable {private static final long serialVersionUID = 1L;/*** 参数主键*/@NotBlank(message = "参数主键不能为空")@Length(max = 30, message = "参数主键不能超过{max}个字符")@ExcelIgnore@Excel(name = "参数主键")@ApiModelProperty(value = "参数主键", required = true, position = 1)private String id;/*** 参数名称*/@NotBlank(message = "参数名称不能为空")@Length(max = 100, message = "参数名称不能超过{max}个字符")@Excel(name = "参数名称", width = 30d)@ApiModelProperty(value = "参数名称", required = true, position = 2)private String name;/*** 参数编码*/@NotBlank(message = "参数编码不能为空")@Length(max = 100, message = "参数编码不能超过{max}个字符")@Excel(name = "参数编码", width = 30d)@ApiModelProperty(value = "参数编码", required = true, position = 3)private String code;/*** 参数值*/@Length(max = 500, message = "参数值不能超过{max}个字符")@Excel(name = "参数值", width = 40d)@ApiModelProperty(value = "参数值", position = 4)private String value;/*** 参数名称简拼*/@Length(max = 100, message = "参数名称简拼不能超过{max}个字符")@ExcelIgnore@Excel(name = "简拼")@ApiModelProperty(value = "参数名称简拼", position = 5)private String spell;/*** 备注*/@Length(max = 200, message = "备注不能超过{max}个字符")@Excel(name = "备注", width = 40d)@ApiModelProperty(value = "备注", position = 100)private String remark;}
使用方法
框架中验证支持在Model类中验证,也支持方法参数验证,所有的验证都在Service层进行。要启用验证需要按以下步骤设置:
- 在需要验证的Service类方法上添加注解@Validated。
/*** 新建参数* @param entity 参数对象*/@Validatedpublic void insert(@ValidParam SysParam entity) {}
- 如果验证Model类,需要在变量前添加注解@ValidParam 。
/*** 新建参数* @param entity 参数对象*/@Validatedpublic void insert(@ValidParam SysParam entity) {}//验证组//@Valid(group = {javax.validation.groups.Default.class, com.xci.groups.InsertGroup.class})//验证默认组合插入组,实体中group什么都不加就是默认组
- 如果是普通的方法参数,直接在变量前添加验证规则。
/*** 根据主键查询单个参数* @param id 参数主键* @return 返回参数对象*/@Validatedpublic SysParam selectById(@NotEmpty(message = "请指定参数主键") String id) {return paramDao.selectById(id);}
Bean Validation 中内置的验证规则:
@Valid 被注释的元素是一个对象,需要检查此对象的所有字段值
@Null 被注释的元素必须为 null
@NotNull 被注释的任何元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Negative 被注释的元素必须是一个负数
@NegativeOrZero 被注释的元素必须是负数或 0
@Positive 被注释的元素必须是一个正数
@PositiveOrZero 被注释的元素必须是一个正数或 0
@Size(max, min) (字符串,集合,数组) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 校验数字小数点前后位数 被注释的元素必须是一个数字,
integer 小数点前几位
fraction 小数点后几位
@Past 被注释的元素必须是一个过去的日期
@PastOrPresent 被注释的元素必须是一个过去或当前的日期
@Future 被注释的元素必须是一个将来的日期
@FutureOrPresent 被注释的元素必须是一个将来或当前的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
@NotEmpty 集合对象的元素不为0,即集合不为空,也可以用于字符串不为 null
@NotBlank 只能用于字符串不为null,并且字符串trim()以后length要大于0
@Email 被注释的元素必须是一个有效的邮箱地址
@Length(min=,max=) 校验字符串的长度
@Range(min=,max=) min <= 数字 <= max
Hibernate Validator 完全遵循了 Bean Validation 的规范,并在其基础上有附加的扩展:
@CreditCardNumber 被注释的字符串必须通过 Luhn 校验算法,银行卡,信用卡等号码一般都用 Luhn 计算合法性
@Currency 被注释的 javax.money.MonetaryAmount 货币元素是否合规
@DurationMax 被注释的元素不能大于指定日期
@DurationMin 被注释的元素不能低于指定日期
@LuhnCheck Luhn 算法校验字符串中指定的部分
@Mod10Check Mod10 算法校验
@Mod11Check Mod11 算法校验
@SafeHtml classpath中要有jsoup包
@ScriptAssert 检查脚本是否可运行
@URL 被注释的字符串必须是一个有效的url
手动验证实体类规则
/*** 校验对象*/@Resourceprivate Validator beanValidator;SysParam entity = new SysParam();Set<ConstraintViolation<SysParam>> result = beanValidator.validate(entity);HashMap<String, String> validatorMap = new HashMap<>();for(ConstraintViolation<Object> aValidResult : validResult) {//字段名:aValidResult.getPropertyPath().toString()//错误消息:aValidResult.getMessage()}
自定义验证规则
https://my.oschina.net/qjx1208/blog/200946
- 验证大小写
public enum CaseMode {UPPER,LOWER;}@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = CheckCaseValidator.class)@Documentedpublic @interface CheckCase {String message() default "";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};CaseMode value();}public class CheckCaseValidator implements ConstraintValidator<CheckCase, String> {private CaseMode caseMode;public void initialize(CheckCase checkCase) {this.caseMode = checkCase.value();}public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {if (s == null) {return true;}if (caseMode == CaseMode.UPPER) {return s.equals(s.toUpperCase());} else {return s.equals(s.toLowerCase());}}}
- 性别约束
/*@Target用于指定使用范围,该处限定只能在字段上使用@Retention(RetentionPolicy.RUNTIME)表示注解在运行时可以通过反射获取到@Constraint(validatedBy = xxx.class)指定该注解校验逻辑*//*** 性别约束*/@Target({ ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = SexConstraintValidator.class)public @interface Sex {String message() default "性别有误";Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };}/*** 性别约束逻辑判断*/public class SexConstraintValidator implements ConstraintValidator<Sex, String> {@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {return value != null && (value.equals("男") || value.equals("女"));}}
