前言
javax.validation 是基于JSR-303标准提供的参数校验规范,使用注解方式实现对参数的校验,极其方便。
比较常用的参数校验注解有:
- @Null 被注解的元素必须为null
- @NotNull 被注解的元素必须不为null
- @AssertTrue 被注解的元素必须为true
- @AssertFalse 被注解的元素必须为false
- @Min(value) 被注解的元素必须为数字,其值必须大于等于最小值
- @Max(value) 被注解的元素必须为数字,其值必须小于等于最小值
- @Size(max,min) 被注解的元素的大小必须在指定范围内
- @Past 被注解的元素必须为过去的一个时间
- @Future 被注解的元素必须为未来的一个时间
- @Pattern 被注解的元素必须符合指定的正则表达式
hibernate里对validation又做了一些拓展,常用的有以下几个:
- @Length 校验字符串的长度是否在指定范围内
- @Range 校验数字的范围
- @URL 校验url是否合法
实现自定义拓展注解校验手机号码
代码部分如下:
具有required属性的基础校验器
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;
}
}
基于正则校验的基础校验器
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两个属性的 校验器
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两个属性的 校验器,
* 子类需要实现{@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();
}
}
自定义手机号码校验注解
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>
* 校验手机号是否合法
*/
@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 "手机号码不合法";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* 是否必须有值
*/
boolean required() default true;
/**
* 号码所在区域
*/
Region region() default Region.MAINLAND;
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@interface List {
Mobile[] value();
}
/**
* 区域
*/
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的校验器
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}实现的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实现的其他注解完全相同,在指定参数加上即可
/**
* 手机号,非必填
*/
@Mobile(required = false)
private String mobile;
网友评论