前言
javax.validation 是基于JSR-303標(biāo)準(zhǔn)提供的參數(shù)校驗(yàn)規(guī)范舆声,使用注解方式實(shí)現(xiàn)對參數(shù)的校驗(yàn)臼朗,極其方便豹缀。
比較常用的參數(shù)校驗(yàn)注解有:
- @Null 被注解的元素必須為null
- @NotNull 被注解的元素必須不為null
- @AssertTrue 被注解的元素必須為true
- @AssertFalse 被注解的元素必須為false
- @Min(value) 被注解的元素必須為數(shù)字藤巢,其值必須大于等于最小值
- @Max(value) 被注解的元素必須為數(shù)字竟纳,其值必須小于等于最小值
- @Size(max,min) 被注解的元素的大小必須在指定范圍內(nèi)
- @Past 被注解的元素必須為過去的一個時間
- @Future 被注解的元素必須為未來的一個時間
- @Pattern 被注解的元素必須符合指定的正則表達(dá)式
hibernate里對validation又做了一些拓展撵溃,常用的有以下幾個:
- @Length 校驗(yàn)字符串的長度是否在指定范圍內(nèi)
- @Range 校驗(yàn)數(shù)字的范圍
- @URL 校驗(yàn)url是否合法
實(shí)現(xiàn)自定義拓展注解校驗(yàn)手機(jī)號碼
代碼部分如下:
具有required屬性的基礎(chǔ)校驗(yàn)器
package com.cube.share.base.constraints.validator;
/**
* @author litb
* @date 2022/3/21 17:55
*/
public class BaseRequiredValidator {
protected boolean required;
public boolean isRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
}
基于正則校驗(yàn)的基礎(chǔ)校驗(yàn)器
package com.cube.share.base.constraints.validator;
import java.util.regex.Pattern;
/**
* @author litb
* @date 2022/3/21 17:56
*/
public class BasePatternValidator extends BaseRequiredValidator {
protected Pattern pattern;
public Pattern getPattern() {
return pattern;
}
public void setPattern(Pattern pattern) {
this.pattern = pattern;
}
}
提供抽象的具有 required 和 pattern兩個屬性的 校驗(yàn)器
package com.cube.share.base.constraints.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.Annotation;
import java.util.regex.Matcher;
/**
* @author litb
* @date 2022/3/21 18:50
* <p>
* 提供抽象的具有 required 和 pattern兩個屬性的 校驗(yàn)器,
* 子類需要實(shí)現(xiàn){@link AbstractPatternValidator#initialize(Annotation)}
*/
public abstract class AbstractPatternValidator<A extends Annotation> extends BasePatternValidator implements ConstraintValidator<A, String> {
/**
* Initializes the validator in preparation for
* {@link #isValid(String, ConstraintValidatorContext)} calls.
* The constraint annotation for a given constraint declaration
* is passed.
* <p>
* This method is guaranteed to be called before any use of this instance for
* validation.
* <p>
* The default implementation is a no-op.
*
* @param constraintAnnotation annotation instance for a given constraint declaration
*/
@Override
public abstract void initialize(A constraintAnnotation);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (!required && value == null) {
return true;
}
if (value == null) {
return false;
}
Matcher matcher = pattern.matcher(value);
return matcher.matches();
}
}
自定義手機(jī)號碼校驗(yàn)注解
package com.cube.share.base.constraints;
import com.cube.share.base.constraints.validator.MobileValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* @author litb
* @date 2022/3/16 10:06
* <p>
* 校驗(yàn)手機(jī)號是否合法
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Repeatable(Mobile.List.class)
@Documented
@Constraint(validatedBy = {MobileValidator.class})
public @interface Mobile {
String message() default "手機(jī)號碼不合法";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* 是否必須有值
*/
boolean required() default true;
/**
* 號碼所在區(qū)域
*/
Region region() default Region.MAINLAND;
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@interface List {
Mobile[] value();
}
/**
* 區(qū)域
*/
enum Region {
/**
* 大陸 (?:0|86|\+86)?1[3-9]\d{9}
*/
MAINLAND,
/**
* 臺灣 (?:0|886|\+886)?(?:|-)09\d{8}
*/
TW,
/**
* 香港 (?:0|852|\+852)?\d{8}
*/
HK,
/**
* 澳門 (?:0|853|\+853)?(?:|-)6\d{7}
*/
MO
}
}
自定義注解@Mobile的校驗(yàn)器
package com.cube.share.base.constraints.validator;
import com.cube.share.base.constraints.ConstraintConstants;
import com.cube.share.base.constraints.Mobile;
/**
* @author litb
* @date 2022/3/21 17:50
* <p>
* 為{@link Mobile}實(shí)現(xiàn)的Validator
*/
public class MobileValidator extends AbstractPatternValidator<Mobile> {
@Override
public void initialize(Mobile annotation) {
required = annotation.required();
Mobile.Region region = annotation.region();
switch (region) {
case MAINLAND:
pattern = ConstraintConstants.MOBILE_MAINLAND_PATTERN;
break;
case HK:
pattern = ConstraintConstants.MOBILE_HK_PATTERN;
break;
case MO:
pattern = ConstraintConstants.MOBILE_MO_PATTERN;
break;
case TW:
pattern = ConstraintConstants.MOBILE_TW_PATTERN;
break;
default:
throw new IllegalArgumentException("unmatched region");
}
}
}
自定義注解@Mobile的用法與validation實(shí)現(xiàn)的其他注解完全相同,在指定參數(shù)加上即可
/**
* 手機(jī)號,非必填
*/
@Mobile(required = false)
private String mobile;