diff --git a/.vscode/settings.json b/.vscode/settings.json index 13f5352..4fa5537 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,5 @@ { "java.configuration.updateBuildConfiguration": "automatic", - "java.dependency.packagePresentation": "hierarchical" -} \ No newline at end of file + "java.dependency.packagePresentation": "hierarchical", + "java.compile.nullAnalysis.mode": "automatic" +} diff --git a/pom.xml b/pom.xml index 8c9f4fd..12d02a5 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,12 @@ - + 4.0.0 xyz.zhouxy.plusone plusone-validator - 0.1.2-SNAPSHOT + 0.1.3-SNAPSHOT plusone-validator http://zhouxy.xyz @@ -15,6 +15,7 @@ UTF-8 1.8 1.8 + 3.12.0 @@ -24,15 +25,21 @@ 0.1.0-SNAPSHOT - junit - junit - 4.11 + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.junit.jupiter + junit-jupiter-api + 5.9.2 test - + + diff --git a/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java b/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java index 1782fc9..847a01d 100644 --- a/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java +++ b/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java @@ -13,7 +13,7 @@ public class BaseValidator { private final List> propertyValidators = new ArrayList<>(); protected void withRule(final Predicate rule, final String errorMessage) { - withRule(rule, value -> new InvalidInputException(errorMessage)); + withRule(rule, () -> InvalidInputException.of(errorMessage)); } protected void withRule(Predicate rule, Supplier exceptionBuilder) { diff --git a/src/main/java/xyz/zhouxy/plusone/validator/BoolValidator.java b/src/main/java/xyz/zhouxy/plusone/validator/BoolValidator.java index 9912c37..fa408f6 100644 --- a/src/main/java/xyz/zhouxy/plusone/validator/BoolValidator.java +++ b/src/main/java/xyz/zhouxy/plusone/validator/BoolValidator.java @@ -3,6 +3,8 @@ package xyz.zhouxy.plusone.validator; import java.util.function.Function; import java.util.function.Supplier; +import org.apache.commons.lang3.BooleanUtils; + public class BoolValidator extends PropertyValidator> { BoolValidator(Function getter) { @@ -25,7 +27,7 @@ public class BoolValidator extends PropertyValidator BoolValidator isTrue( Function exceptionCreator) { - withRule(Boolean.TRUE::equals, exceptionCreator); + withRule(BooleanUtils::isTrue, exceptionCreator); return this; } @@ -45,10 +47,10 @@ public class BoolValidator extends PropertyValidator BoolValidator isFalse( Function exceptionCreator) { - withRule(Boolean.FALSE::equals, exceptionCreator); + withRule(BooleanUtils::isFalse, exceptionCreator); return this; } - + @Override protected BoolValidator thisObject() { return this; diff --git a/src/main/java/xyz/zhouxy/plusone/validator/CollectionValidator.java b/src/main/java/xyz/zhouxy/plusone/validator/CollectionValidator.java index 5a79048..cb434a1 100644 --- a/src/main/java/xyz/zhouxy/plusone/validator/CollectionValidator.java +++ b/src/main/java/xyz/zhouxy/plusone/validator/CollectionValidator.java @@ -22,12 +22,7 @@ public class CollectionValidator extends PropertyValidator CollectionValidator notEmpty( Function, E> exceptionCreator) { - withRule(value -> { - if (value == null) { - return false; - } - return !((Collection) value).isEmpty(); - }, exceptionCreator); + withRule(value -> value != null && !value.isEmpty(), exceptionCreator); return this; } @@ -43,12 +38,7 @@ public class CollectionValidator extends PropertyValidator CollectionValidator isEmpty( Function, E> exceptionCreator) { - withRule(value -> { - if (value == null) { - return false; - } - return ((Collection) value).isEmpty(); - }, exceptionCreator); + withRule(value -> value == null || value.isEmpty(), exceptionCreator); return this; } diff --git a/src/main/java/xyz/zhouxy/plusone/validator/IntValidator.java b/src/main/java/xyz/zhouxy/plusone/validator/IntValidator.java index 29fc24f..1cdf093 100644 --- a/src/main/java/xyz/zhouxy/plusone/validator/IntValidator.java +++ b/src/main/java/xyz/zhouxy/plusone/validator/IntValidator.java @@ -10,7 +10,7 @@ public class IntValidator extends PropertyValidator between(int min, int max) { - return between(min, max, String.format("数值不在 %s 和 %s 之间", String.valueOf(min), String.valueOf(max))); + return between(min, max, String.format("数值不在 %d 和 %d 之间", min, max)); } public IntValidator between(int min, int max, String errMsg) { diff --git a/src/main/java/xyz/zhouxy/plusone/validator/InvalidInputException.java b/src/main/java/xyz/zhouxy/plusone/validator/InvalidInputException.java index b770344..1bc1c30 100644 --- a/src/main/java/xyz/zhouxy/plusone/validator/InvalidInputException.java +++ b/src/main/java/xyz/zhouxy/plusone/validator/InvalidInputException.java @@ -1,53 +1,39 @@ package xyz.zhouxy.plusone.validator; -import xyz.zhouxy.plusone.exception.BaseException; +import xyz.zhouxy.plusone.commons.exception.BaseRuntimeException; /** - * 4040200 - 无效的用户输入 + * 4040000 - 用户请求参数错误 * * @author ZhouXY */ -public class InvalidInputException extends BaseException { +public class InvalidInputException extends BaseRuntimeException { private static final long serialVersionUID = 7956661913360059670L; - public static final int ERROR_CODE = 4040200; + public static final String ERROR_CODE = "4040000"; - private InvalidInputException(int code, String msg) { + protected InvalidInputException(String code, String msg) { super(code, msg); } - private InvalidInputException(int code, Throwable cause) { + protected InvalidInputException(String code, Throwable cause) { super(code, cause); } - private InvalidInputException(int code, String msg, Throwable cause) { + protected InvalidInputException(String code, String msg, Throwable cause) { super(code, msg, cause); } - public InvalidInputException(String msg) { - this(ERROR_CODE, msg); + public static InvalidInputException of(String msg) { + return new InvalidInputException(ERROR_CODE, msg); } - public InvalidInputException(Throwable cause) { - this(ERROR_CODE, cause); + public static InvalidInputException of(Throwable cause) { + return new InvalidInputException(ERROR_CODE, cause); } - public InvalidInputException(String msg, Throwable cause) { - this(ERROR_CODE, msg, cause); - } - - /** - * 不支持的 Principal 类型出现时抛出的异常 - */ - public static InvalidInputException unsupportedPrincipalTypeException() { - return unsupportedPrincipalTypeException("不支持的 PrincipalType"); - } - - /** - * 不支持的 Principal 类型出现时抛出的异常 - */ - public static InvalidInputException unsupportedPrincipalTypeException(String message) { - return new InvalidInputException(4040201, message); + public static InvalidInputException of(String msg, Throwable cause) { + return new InvalidInputException(ERROR_CODE, msg, cause); } } diff --git a/src/main/java/xyz/zhouxy/plusone/validator/PropertyValidator.java b/src/main/java/xyz/zhouxy/plusone/validator/PropertyValidator.java index 2adf9b9..2dafff3 100644 --- a/src/main/java/xyz/zhouxy/plusone/validator/PropertyValidator.java +++ b/src/main/java/xyz/zhouxy/plusone/validator/PropertyValidator.java @@ -69,7 +69,7 @@ abstract class PropertyValidator { // ===== equals ===== public THIS equalsThat(Object that) { - return equalsThat(that, value -> new InvalidInputException(String.format("(%s) 必须与 (%s) 相等", value, that))); + return equalsThat(that, value -> InvalidInputException.of(String.format("(%s) 必须与 (%s) 相等", value, that))); } public THIS equalsThat(Object that, String errMsg) { @@ -87,46 +87,46 @@ abstract class PropertyValidator { return thisObject(); } - // ===== state ===== + // ===== isTrue ===== - public THIS state(Predicate condition) { - return state(condition, "无效的用户输入"); + public THIS isTrue(Predicate condition) { + return isTrue(condition, "无效的用户输入"); } - public THIS state(Predicate condition, String errMsg) { - return state(condition, convertExceptionCreator(errMsg)); + public THIS isTrue(Predicate condition, String errMsg) { + return isTrue(condition, convertExceptionCreator(errMsg)); } - public THIS state( + public THIS isTrue( Predicate condition, Supplier exceptionCreator) { - return state(condition, convertExceptionCreator(exceptionCreator)); + return isTrue(condition, convertExceptionCreator(exceptionCreator)); } - public THIS state( + public THIS isTrue( Predicate condition, Function exceptionCreator) { withRule(condition, exceptionCreator); return thisObject(); } - // ===== state ===== + // ===== isTrue ===== - public THIS state(Collection> conditions) { - return state(conditions, "无效的用户输入"); + public THIS isTrue(Collection> conditions) { + return isTrue(conditions, "无效的用户输入"); } - public THIS state(Collection> conditions, String errMsg) { - return state(conditions, convertExceptionCreator(errMsg)); + public THIS isTrue(Collection> conditions, String errMsg) { + return isTrue(conditions, convertExceptionCreator(errMsg)); } - public THIS state( + public THIS isTrue( Collection> conditions, Supplier exceptionCreator) { - return state(conditions, convertExceptionCreator(exceptionCreator)); + return isTrue(conditions, convertExceptionCreator(exceptionCreator)); } - public THIS state( + public THIS isTrue( Collection> conditions, Function exceptionCreator) { for (Predicate condition : conditions) { @@ -143,7 +143,7 @@ abstract class PropertyValidator { } static Function convertExceptionCreator(String errMsg) { - return value -> new InvalidInputException(errMsg); + return value -> InvalidInputException.of(errMsg); } static Function convertExceptionCreator( diff --git a/src/main/java/xyz/zhouxy/plusone/validator/StringValidator.java b/src/main/java/xyz/zhouxy/plusone/validator/StringValidator.java index 7e02756..77824e3 100644 --- a/src/main/java/xyz/zhouxy/plusone/validator/StringValidator.java +++ b/src/main/java/xyz/zhouxy/plusone/validator/StringValidator.java @@ -1,12 +1,15 @@ package xyz.zhouxy.plusone.validator; +import java.util.Collection; import java.util.List; import java.util.function.Function; import java.util.function.Supplier; +import java.util.regex.Pattern; -import cn.hutool.core.util.StrUtil; -import xyz.zhouxy.plusone.constant.RegexConsts; -import xyz.zhouxy.plusone.util.RegexUtil; +import org.apache.commons.lang3.StringUtils; + +import xyz.zhouxy.plusone.commons.constant.PatternConsts; +import xyz.zhouxy.plusone.commons.util.RegexUtil; public class StringValidator extends PropertyValidator> { @@ -20,75 +23,92 @@ public class StringValidator extends PropertyValidator matches(String regex, String errMsg) { + public StringValidator matches(Pattern regex, String errMsg) { return matches(regex, convertExceptionCreator(errMsg)); } public StringValidator matches( - String regex, + Pattern regex, Supplier exceptionCreator) { return matches(regex, convertExceptionCreator(exceptionCreator)); } public StringValidator matches( - String regex, + Pattern regex, Function exceptionCreator) { withRule(input -> RegexUtil.matches(input, regex), exceptionCreator); return this; } - // ===== matchesOr ===== + // ===== matchesOne ===== - public StringValidator matchesOr(String[] regexs, String errMsg) { - return matchesOr(regexs, convertExceptionCreator(errMsg)); + public StringValidator matchesOne(Pattern[] regexs, String errMsg) { + return matchesOne(regexs, convertExceptionCreator(errMsg)); } - public StringValidator matchesOr( - String[] regexs, + public StringValidator matchesOne( + Pattern[] regexs, Supplier exceptionCreator) { - return matchesOr(regexs, convertExceptionCreator(exceptionCreator)); + return matchesOne(regexs, convertExceptionCreator(exceptionCreator)); } - public StringValidator matchesOr( - String[] regexs, + public StringValidator matchesOne( + Pattern[] regexs, Function exceptionCreator) { - withRule(input -> RegexUtil.matchesOr(input, regexs), exceptionCreator); + withRule(input -> RegexUtil.matchesOne(input, regexs), exceptionCreator); return this; } - public StringValidator matchesOr(List regexs, String errMsg) { - return matchesOr(regexs, convertExceptionCreator(errMsg)); + public StringValidator matchesOne(List regexs, String errMsg) { + return matchesOne(regexs, convertExceptionCreator(errMsg)); } - public StringValidator matchesOr( - List regexs, + public StringValidator matchesOne( + List regexs, Supplier exceptionCreator) { - return matchesOr(regexs, convertExceptionCreator(exceptionCreator)); + return matchesOne(regexs, convertExceptionCreator(exceptionCreator)); } - public StringValidator matchesOr( - List regexs, + public StringValidator matchesOne( + List regexs, Function exceptionCreator) { - withRule(input -> RegexUtil.matchesOr(input, regexs.toArray(new String[regexs.size()])), exceptionCreator); + withRule(input -> RegexUtil.matchesOne(input, regexs.toArray(new Pattern[regexs.size()])), exceptionCreator); return this; } - // ===== matchesAnd ===== + // ===== matchesAll ===== - public StringValidator matchesAnd(String[] regexs, String errMsg) { - return matchesAnd(regexs, convertExceptionCreator(errMsg)); + public StringValidator matchesAll(Pattern[] regexs, String errMsg) { + return matchesAll(regexs, convertExceptionCreator(errMsg)); } - public StringValidator matchesAnd( - String[] regexs, + public StringValidator matchesAll( + Pattern[] regexs, Supplier exceptionCreator) { - return matchesAnd(regexs, convertExceptionCreator(exceptionCreator)); + return matchesAll(regexs, convertExceptionCreator(exceptionCreator)); } - public StringValidator matchesAnd( - String[] regexs, + public StringValidator matchesAll( + Pattern[] regexs, Function exceptionCreator) { - withRule(input -> RegexUtil.matchesAnd(input, regexs), exceptionCreator); + withRule(input -> RegexUtil.matchesAll(input, regexs), exceptionCreator); + return this; + } + + public StringValidator matchesAll(Collection regexs, String errMsg) { + return matchesAll(regexs, convertExceptionCreator(errMsg)); + } + + public StringValidator matchesAll( + Collection regexs, + Supplier exceptionCreator) { + return matchesAll(regexs, convertExceptionCreator(exceptionCreator)); + } + + public StringValidator matchesAll( + Collection regexs, + Function exceptionCreator) { + withRule(input -> RegexUtil.matchesAll(input, regexs.toArray(new Pattern[regexs.size()])), exceptionCreator); return this; } @@ -108,7 +128,7 @@ public class StringValidator extends PropertyValidator StringValidator notBlank( Function exceptionCreator) { - withRule(input -> StrUtil.isNotBlank(input), exceptionCreator); + withRule(StringUtils::isNotBlank, exceptionCreator); return this; } @@ -127,7 +147,7 @@ public class StringValidator extends PropertyValidator StringValidator email(Function exceptionCreator) { - return matches(RegexConsts.EMAIL, exceptionCreator); + return matches(PatternConsts.EMAIL, exceptionCreator); } // ====== notEmpty ===== @@ -142,12 +162,7 @@ public class StringValidator extends PropertyValidator StringValidator notEmpty( Function exceptionCreator) { - withRule(value -> { - if (value == null) { - return false; - } - return !(value.isEmpty()); - }, exceptionCreator); + withRule(StringUtils::isNotEmpty, exceptionCreator); return this; } @@ -163,12 +178,7 @@ public class StringValidator extends PropertyValidator StringValidator isEmpty( Function exceptionCreator) { - withRule(value -> { - if (value == null) { - return false; - } - return value.isEmpty(); - }, exceptionCreator); + withRule(StringUtils::isEmpty, exceptionCreator); return this; } diff --git a/src/main/java/xyz/zhouxy/plusone/validator/Validator.java b/src/main/java/xyz/zhouxy/plusone/validator/Validator.java index bbe12ad..f5a730a 100644 --- a/src/main/java/xyz/zhouxy/plusone/validator/Validator.java +++ b/src/main/java/xyz/zhouxy/plusone/validator/Validator.java @@ -47,7 +47,7 @@ public final class Validator extends BaseValidator { withRule(rule, exceptionCreator); return this; } - + public final Validator addRule(Predicate rule, Function exceptionCreator) { withRule(rule, exceptionCreator); return this; diff --git a/src/test/java/xyz/zhouxy/plusone/validator/test/BaseValidatorTest.java b/src/test/java/xyz/zhouxy/plusone/validator/test/BaseValidatorTest.java index d9ffe81..d6e2927 100644 --- a/src/test/java/xyz/zhouxy/plusone/validator/test/BaseValidatorTest.java +++ b/src/test/java/xyz/zhouxy/plusone/validator/test/BaseValidatorTest.java @@ -4,15 +4,18 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -import org.junit.Test; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Test; -import xyz.zhouxy.plusone.constant.RegexConsts; +import xyz.zhouxy.plusone.commons.constant.PatternConsts; +import xyz.zhouxy.plusone.commons.function.Predicates; +import xyz.zhouxy.plusone.commons.util.RegexUtil; import xyz.zhouxy.plusone.validator.BaseValidator; import xyz.zhouxy.plusone.validator.ValidateUtil; -public class BaseValidatorTest { +class BaseValidatorTest { @Test - public void testValidate() { + void testValidate() { RegisterCommand registerCommand = new RegisterCommand("zhouxy108", "luquanlion@outlook.com", "22336", "A1b2C3d4", "A1b2C3d4", Arrays.asList(new String[] { "admin", "editor" })); @@ -28,18 +31,20 @@ class RegisterCommandValidator extends BaseValidator { private RegisterCommandValidator() { ruleForString(RegisterCommand::getUsername) - .notNull("用户名不能为空") - .matches(RegexConsts.USERNAME, - username -> new IllegalArgumentException(String.format("用户名\"%s\"不符合规范", username))); + .isTrue(Predicates.of(Objects::nonNull) + .and(StringUtils::isNotEmpty) + .and(StringUtils::isNotBlank) + .and(username -> RegexUtil.matches(username, PatternConsts.USERNAME)), + username -> new IllegalArgumentException(String.format("用户名【%s】不符合规范", username))); ruleForString(RegisterCommand::getAccount) .notNull("请输入邮箱地址或手机号") - .matchesOr(new String[] { RegexConsts.EMAIL, RegexConsts.MOBILE_PHONE }, "请输入邮箱地址或手机号"); + .matchesOne(Arrays.asList(PatternConsts.EMAIL, PatternConsts.MOBILE_PHONE), "请输入邮箱地址或手机号"); ruleForString(RegisterCommand::getCode) .notNull("验证码不能为空") - .matches(RegexConsts.CAPTCHA, "验证码不符合规范"); + .matches(PatternConsts.CAPTCHA, "验证码不符合规范"); ruleForString(RegisterCommand::getPassword) .notEmpty("密码不能为空") - .matches(RegexConsts.PASSWORD, "密码不符合规范"); + .matches(PatternConsts.PASSWORD, "密码不符合规范"); ruleForCollection(RegisterCommand::getRoles) .notEmpty(() -> new RuntimeException("角色列表不能为空")); diff --git a/src/test/java/xyz/zhouxy/plusone/validator2/test/ValidatorTests.java b/src/test/java/xyz/zhouxy/plusone/validator2/test/ValidatorTests.java new file mode 100644 index 0000000..372052d --- /dev/null +++ b/src/test/java/xyz/zhouxy/plusone/validator2/test/ValidatorTests.java @@ -0,0 +1,147 @@ +package xyz.zhouxy.plusone.validator2.test; + +import static xyz.zhouxy.plusone.commons.constant.PatternConsts.*; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Test; + +import com.google.common.base.Preconditions; + +import xyz.zhouxy.plusone.commons.function.Predicates; +import xyz.zhouxy.plusone.commons.util.MoreCollections; +import xyz.zhouxy.plusone.commons.util.RegexUtil; +import xyz.zhouxy.plusone.validator.Validator; + +class ValidatorTests { + @Test + void testValidate() { + RegisterCommand registerCommand = new RegisterCommand( + "null", "luquanlion@outlook.com", "22336", + "A1b2C3d4", "A1b2C3d4", + Arrays.asList(new String[] { "admin", "editor" })); + + Validator registerCommandValidator = new Validator() + // 传入 predicate 和 Function + .addRule(command -> { + String username = command.getUsername(); + return Objects.nonNull(username) + && StringUtils.isNotEmpty(username) + && StringUtils.isNotBlank(username) + && RegexUtil.matches(username, USERNAME); + }, command -> new IllegalArgumentException(String.format("用户名【%s】不符合规范", command.getUsername()))) + // 传入 predicate 和 error message + .addRule(command -> Predicates + .of(Objects::nonNull) + .and(account -> RegexUtil.matchesOne(account, new Pattern[] { EMAIL, MOBILE_PHONE })) + .test(command.getAccount()), + "请输入邮箱地址或手机号") + // 传入 rule + .addRule(command -> { + String code = command.getCode(); + Preconditions.checkArgument(Objects.nonNull(code), "验证码不能为空"); + Preconditions.checkArgument(RegexUtil.matches(code, CAPTCHA), "验证码不符合规范"); + }) + // 传入 rule + .addRule(command -> { + String password = command.getPassword(); + Preconditions.checkArgument(StringUtils.isNotEmpty(password), "密码不能为空"); + Preconditions.checkArgument(RegexUtil.matches(password, PASSWORD), "密码不符合规范"); + }) + // 传入 predicate 和 Supplier + .addRule(command -> MoreCollections.isNotEmpty(command.getRoles()), + () -> new RuntimeException("角色列表不能为空")) + // 传入 predicate 和 error message + .addRule(command -> Objects.equals(command.getPassword(), command.getPassword2()), + "两次输入的密码不一致"); + registerCommandValidator.validate(registerCommand); + System.out.println(registerCommand); + } +} + +/** + * RegisterCommand + */ +class RegisterCommand { + + private String username; + private String account; + private String code; + private String password; + private String password2; + private List roles; + + public RegisterCommand() { + } + + public RegisterCommand(String username, String account, String code, String password, String password2, + List roles) { + this.username = username; + this.account = account; + this.code = code; + this.password = password; + this.password2 = password2; + this.roles = roles; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword2() { + return password2; + } + + public void setPassword2(String password2) { + this.password2 = password2; + } + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("RegisterCommand [username=").append(username).append(", account=").append(account) + .append(", code=").append(code).append(", password=").append(password).append(", password2=") + .append(password2).append(", roles=").append(roles).append("]"); + return builder.toString(); + } +}