在web开发中,相信大部分的同学用的都是基于spring的框架,不管是spring framework还是spring boot。在spring的使用过程中,避免不了一些参数校验,很体贴的,有一些现成的可以使用,例如判断长度、大小等,具体可参考JSR303和JSR380,380较303而言,是比较新的标准。
下面的表格整理自validation-api-2.0.0.Final.jar
Constraint | 详细信息 |
---|---|
@AssertFalse | 该值必须为False |
@AssertTrue | 该值必须为True |
@DecimalMax(value,inclusive) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 ,inclusive表示是否包含该值 |
@DecimalMin(value,inclusive) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 ,inclusive表示是否包含该值 |
@Digits | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
该值必须为邮箱格式 | |
@Future | 被注释的元素必须是一个将来的日期 |
@FutureOrPresent | 被注释的元素必须是一个现在或将来的日期 |
@Max(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@Min(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Negative | 该值必须小于0 |
@NegativeOrZero | 该值必须小于等于0 |
@NotBlank | 该值不为空字符串,例如“ ” |
@NotEmpty | 该值不为空字符串 |
@NotNull | 该值不为Null |
@Null | 该值必须为Null |
@Past | 被注释的元素必须是一个过去的日期 |
@PastOrPresent | 被注释的元素必须是一个过去或现在的日期 |
@Pattern(regexp) | 匹配正则 |
@Positive | 该值必须大于0 |
@PositiveOrZero | 该值必须大于等于0 |
@Size(min,max) | 数组大小必须在[min,max]这个区间 |
另外hibernate的validator包hibernate-validator-6.0.2Final.jar中,又扩展了一些校验
Constraint | 详细信息 |
---|---|
@CNPJ | CNPJ是巴西联邦税务局秘书处向巴西公司发放的身份证号码,这个注解校验的就是该号码 |
@CreditCardNumber(ignoreNonDigitCharacters=) | 被注释的字符串必须通过 Luhn 校验算法,银行卡,信用卡等号码一般都用 Luhn 计算合法性 |
@Currency(value=) | 被注释的 javax.money.MonetaryAmount 货币元素是否合规 |
@DurationMax(days=, hours=, minutes=, seconds=, millis=, nanos=, inclusive=) | 被注释的元素不能大于指定日期 |
@DurationMin(days=, hours=, minutes=, seconds=, millis=, nanos=, inclusive=) | 被注释的元素不能低于指定日期 |
@EAN | 被注释的元素是否是一个有效的 EAN 条形码 |
@Length(min=, max=) | 被注释的字符串的大小必须在指定的范围内 |
@LuhnCheck(startIndex= , endIndex=, checkDigitIndex=, ignoreNonDigitCharacters=) | Luhn 算法校验字符串中指定的部分 |
@Mod10Check(multiplier=, weight=, startIndex=, endIndex=, checkDigitIndex=, ignoreNonDigitCharacters=) | Mod10 算法校验 |
@Mod11Check(threshold=, startIndex=, endIndex=, checkDigitIndex=, ignoreNonDigitCharacters=, treatCheck10As=, treatCheck11As=) | Mod11 算法校验 |
@Range(min=, max=) | 被注释的元素必须在合适的范围内 |
@SafeHtml(whitelistType= , additionalTags=, additionalTagsWithAttributes=, baseURI=) | classpath中要有jsoup包,校验是否为安全html,即无注入信息 |
@ScriptAssert(lang=, script=, alias=, reportOn=) | 检查脚本是否可运行 |
@URL(protocol=, host=, port=, regexp=, flags=) | 被注释的字符串必须是一个有效的url |
通过上述的注解,可以满足我们绝大部分的校验需求,但是在一些场景下,比如一个校验参数里面的值是一个可变量,这个时候想要用这些现成的就比较困难了。例如下面一个类,我需要校验index的范围不能超过ss数组的下标
public class Greeting {
private String[] ss;
private long id;
private String content;
private int index;
使用现成的注解无法满足我们的要求,还好spring给了我们一个自定义的机会。
自定义注解
首先我们需要定义一个注解,写法如下
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy ={IndexValidator.class} )
public @interface IndexConstraint {
String message() default "{params.error}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
其中"{params.error}"
表示默认的错误信息,使用大括号表示从错误信息的文件里面读取,我们可以从hibernate的jar包中拷贝一份出来自己修改,例如
其中ValidationMessages_zh_CN.properties
的内容为
params.error=参数错误
custom.error=下标越界
如果使用idea工具,请勾选这个配置
另外@Constraint(validatedBy ={IndexValidator.class} )
这部分指定使用IndexValidator
来进行校验的操作,IndexValidator
示例如下
public class IndexValidator implements ConstraintValidator<IndexConstraint,Greeting> {
@Override
public boolean isValid(Greeting greeting, ConstraintValidatorContext constraintValidatorContext) {
if(greeting.getIndex()>-1 && greeting.getIndex()<greeting.getSs().length){
return true;
}
//禁止默认消息返回
constraintValidatorContext.disableDefaultConstraintViolation();
//自定义返回消息
constraintValidatorContext.buildConstraintViolationWithTemplate("{custom.error}").addConstraintViolation();
return false;
}
}
测试结果如下
借鉴
https://blog.csdn.net/y550918116j/article/details/78258916
感谢阅读!