feat: 实现手机号校验

This commit is contained in:
wangyu 2021-09-27 17:50:56 +08:00
parent 10b813142b
commit b110813474
9 changed files with 270 additions and 13 deletions

View File

@ -15,24 +15,13 @@ import org.springframework.stereotype.Component;
@Component @Component
public class SpringContext implements ApplicationContextAware { public class SpringContext implements ApplicationContextAware {
private ApplicationContext applicationContext;
private static SpringContext INSTANCE; private static SpringContext INSTANCE;
private ApplicationContext applicationContext;
public SpringContext() { public SpringContext() {
INSTANCE = this; INSTANCE = this;
} }
/**
* 设置上下文
*
* @see BeanInitializationException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/** /**
* 通过类获取某个bean * 通过类获取某个bean
* 优先获取@Prmary注解的bean * 优先获取@Prmary注解的bean
@ -45,8 +34,28 @@ public class SpringContext implements ApplicationContextAware {
return getInstance().applicationContext.getBean(clazz); return getInstance().applicationContext.getBean(clazz);
} }
/**
* 通过name获取 Bean.
*
* @param name bean名称
* @return 结果
*/
public static Object getBean(String name) {
return getInstance().applicationContext.getBean(name);
}
private static SpringContext getInstance() { private static SpringContext getInstance() {
Assert.notNull(INSTANCE, "spring工具类初始化失败请检查该bean是否注入"); Assert.notNull(INSTANCE, "spring工具类初始化失败请检查该bean是否注入");
return INSTANCE; return INSTANCE;
} }
/**
* 设置上下文
*
* @see BeanInitializationException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
} }

View File

@ -0,0 +1,40 @@
package com.flyfish.framework.validation.annotations;
import com.flyfish.framework.validation.validators.ContainsBeanValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 校验是不是JSONString
*
* @author wangyu
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {ContainsBeanValidator.class})
public @interface ContainsBean {
String message() default "未找到容器内的bean";
//分组
Class<?>[] groups() default {};
//负载
Class<? extends Payload>[] payload() default {};
//指定多个时使用
@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@interface List {
IsJSONString[] value();
}
}

View File

@ -0,0 +1,40 @@
package com.flyfish.framework.validation.annotations;
import com.flyfish.framework.validation.validators.IsJSONStringValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 校验是不是JSONString
*
* @author wangyu
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {IsJSONStringValidator.class})
public @interface IsJSONString {
String message() default "字段值必须是JSON字符串";
//分组
Class<?>[] groups() default {};
//负载
Class<? extends Payload>[] payload() default {};
//指定多个时使用
@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@interface List {
IsJSONString[] value();
}
}

View File

@ -0,0 +1,44 @@
package com.flyfish.framework.validation.annotations;
import com.flyfish.framework.validation.enums.PhoneType;
import com.flyfish.framework.validation.validators.IsJSONStringValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 校验是不是JSONString
*
* @author wangyu
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {IsJSONStringValidator.class})
public @interface Phone {
String message() default "不是合法的电话号码!";
//分组
Class<?>[] groups() default {};
//负载
Class<? extends Payload>[] payload() default {};
//类型默认是全部
PhoneType type() default PhoneType.ALL;
//指定多个时使用
@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@interface List {
Phone[] value();
}
}

View File

@ -0,0 +1,9 @@
package com.flyfish.framework.validation.enums;
/**
* 电话类型
*/
public enum PhoneType {
TEL, MOBILE, ALL
}

View File

@ -0,0 +1,27 @@
package com.flyfish.framework.validation.validators;
import com.flyfish.framework.context.SpringContext;
import com.flyfish.framework.validation.annotations.ContainsBean;
import org.apache.commons.lang3.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 包含在ioc容器的bean
*
* @author wangyu
*/
public class ContainsBeanValidator implements ConstraintValidator<ContainsBean, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
if (StringUtils.isBlank(value)) return true;
try {
SpringContext.getBean(value);
return true;
} catch (Exception ignored) {
return false;
}
}
}

View File

@ -0,0 +1,29 @@
package com.flyfish.framework.validation.validators;
import com.flyfish.framework.validation.annotations.IsJSONString;
import org.apache.commons.lang3.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 是否是jsonString
*
* @author wangyu
*/
public class IsJSONStringValidator implements ConstraintValidator<IsJSONString, String> {
/**
* 是否是可用的
*
* @param value
* @param constraintValidatorContext 上下文
* @return 结果
*/
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
if (StringUtils.isBlank(value)) return true;
return value.startsWith("{") && value.endsWith("}")
|| value.startsWith("[") && value.endsWith("]");
}
}

View File

@ -0,0 +1,55 @@
package com.flyfish.framework.validation.validators;
import com.flyfish.framework.validation.annotations.Phone;
import com.flyfish.framework.validation.enums.PhoneType;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
/**
* 判断是否是合法的电话号码
* 会同时判定手机号或固话固话拥有固定格式
* 可以通过制定枚举仅判断某一项
* @author wangyu
*/
public class PhoneValidator implements ConstraintValidator<Phone, String> {
private PhoneType type;
private static final Pattern mobile = Pattern.compile("^1[3,5]\\d{9}||18[6,8,9]\\d{8}$");
private static final Pattern tel = Pattern.compile("^[0][1-9]{2,3}-[0-9]{5,10}$");
@Override
public void initialize(Phone phone) {
this.type = phone.type();
}
/**
* 电话号码的校验逻辑
* 支持类型拾取
* @return 返回成功和失败
*/
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (type == PhoneType.ALL) {
return isMobile(value) || isTel(value);
}
if (type == PhoneType.MOBILE) {
return isMobile(value);
}
if (type == PhoneType.TEL) {
return isTel(value);
}
return false;
}
private boolean isMobile(String value) {
return mobile.matcher(value).matches();
}
private boolean isTel(String value) {
return tel.matcher(value).matches();
}
}

View File

@ -1,6 +1,7 @@
package com.flyfish.framework.beans.enums; package com.flyfish.framework.beans.enums;
import com.flyfish.framework.beans.meta.BeanValidation; import com.flyfish.framework.beans.meta.BeanValidation;
import com.flyfish.framework.validation.enums.PhoneType;
import lombok.Getter; import lombok.Getter;
import org.hibernate.validator.constraints.Currency; import org.hibernate.validator.constraints.Currency;
import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Length;
@ -61,7 +62,10 @@ public enum ValidationCandidate {
.prop("type", annotation.getType().getSimpleName()), .prop("type", annotation.getType().getSimpleName()),
Negative.class, NegativeOrZero.class, Positive.class, PositiveOrZero.class), Negative.class, NegativeOrZero.class, Positive.class, PositiveOrZero.class),
// 货币 // 货币
CURRENCY((annotation, validation) -> validation.setValidator("currency"), Currency.class); CURRENCY((annotation, validation) -> validation.setValidator("currency"), Currency.class),
// 手机号
PHONE(((annotation, validation) -> validation.setValidator("phone")
.prop("type", annotation.getEnum("type", PhoneType.class).name().toLowerCase())));
private final BiConsumer<MergedAnnotation<?>, BeanValidation> mapper; private final BiConsumer<MergedAnnotation<?>, BeanValidation> mapper;