diff --git a/plusone-basic/plusone-basic-common/pom.xml b/plusone-basic/plusone-basic-common/pom.xml
index d3d662d..8864cb3 100644
--- a/plusone-basic/plusone-basic-common/pom.xml
+++ b/plusone-basic/plusone-basic-common/pom.xml
@@ -36,6 +36,11 @@
plusone-commons
0.0.1-SNAPSHOT
+
+ xyz.zhouxy.plusone
+ plusone-validator
+ 0.0.1-SNAPSHOT
+
xyz.zhouxy.plusone
plusone-exception-handler
diff --git a/plusone-basic/plusone-basic-common/src/main/java/xyz/zhouxy/plusone/exception/InvalidInputException.java b/plusone-basic/plusone-basic-common/src/main/java/xyz/zhouxy/plusone/exception/InvalidInputException.java
deleted file mode 100644
index f2a3be9..0000000
--- a/plusone-basic/plusone-basic-common/src/main/java/xyz/zhouxy/plusone/exception/InvalidInputException.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package xyz.zhouxy.plusone.exception;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-/**
- * 4040200 - 无效的用户输入
- *
- * @author ZhouXY
- */
-@ResponseStatus(HttpStatus.BAD_REQUEST)
-public class InvalidInputException extends PlusoneException {
-
- @java.io.Serial
- private static final long serialVersionUID = 7956661913360059670L;
-
- public static final int ERROR_CODE = 4040200;
-
- private InvalidInputException(int code, String msg) {
- super(code, msg);
- }
-
- private InvalidInputException(int code, Throwable cause) {
- super(code, cause);
- }
-
- private InvalidInputException(int code, String msg, Throwable cause) {
- super(code, msg, cause);
- }
-
- public InvalidInputException(String msg) {
- this(ERROR_CODE, msg);
- }
-
- public InvalidInputException(Throwable cause) {
- this(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);
- }
-}
diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java
deleted file mode 100644
index 7a7d9a8..0000000
--- a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package xyz.zhouxy.plusone.validator;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-
-import xyz.zhouxy.plusone.exception.InvalidInputException;
-
-/**
- * 校验器
- *
- *
- * 可以使用以下方式初始化一个校验器:
- *
- *
- *
- * BaseValidator<Integer> validator = new BaseValidator<>() {
- * {
- * withRule(value -> Objects.nonNull(value), "value 不能为空");
- * withRule(value -> (value >= 0 && value <= 500), "value 应在 [0, 500] 内");
- * }
- * };
- *
- *
- *
- * 也可以通过继承本类,定义一个校验器(可使用单例模式)。
- *
- *
- *
- * 然后通过校验器的 {@link #validate} 方法,或
- * {@link ValidateUtil#validate(Object, Validator)} 对指定对象进行校验。
- *
- *
- *
- * ValidateUtil.validate(255, validator);
- *
- *
- *
- * validator.validate(666);
- *
- *
- *
- * @author ZhouXY
- * @see IValidateRequired
- * @see ValidateUtil
- * @see Validator
- */
-public abstract class BaseValidator {
-
- private final List> rules = new ArrayList<>();
-
- protected BaseValidator() {
- }
-
- protected final void withRule(Predicate rule, String errorMessage) {
- withRule(rule, () -> new InvalidInputException(errorMessage));
- }
-
- protected final void withRule(Predicate rule, Supplier exceptionCreator) {
- withRule(rule, value -> exceptionCreator.get());
- }
-
- protected final void withRule(Predicate rule, Function exceptionCreator) {
- this.rules.add(new RuleInfo<>(rule, exceptionCreator));
- }
-
- public void validate(T obj) {
- this.rules.forEach(ruleInfo -> ruleInfo.validate(obj));
- }
-
- protected static class RuleInfo {
- private final Predicate rule;
- private final Function exceptionCreator;
-
- private RuleInfo(Predicate rule, Function exceptionCreator) {
- this.rule = rule;
- this.exceptionCreator = exceptionCreator;
- }
-
- private void validate(T obj) {
- if (!rule.test(obj)) {
- throw exceptionCreator.apply(obj);
- }
- }
- }
-}
diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/IValidateRequired.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/IValidateRequired.java
deleted file mode 100644
index 82e98ae..0000000
--- a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/IValidateRequired.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package xyz.zhouxy.plusone.validator;
-
-/**
- * 自带校验方法,校验不通过时直接抛异常。
- *
- * @author ZhouXY
- *
- * @see ValidateUtil
- * @see BaseValidator
- */
-public interface IValidateRequired {
- void validate();
-}
diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/ValidateUtil.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/ValidateUtil.java
deleted file mode 100644
index 1a8438d..0000000
--- a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/ValidateUtil.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package xyz.zhouxy.plusone.validator;
-
-/**
- * 校验工具类
- *
- * 对 {@link IValidateRequired} 的实现类对象进行校验
- *
- *
- * @author ZhouXY
- *
- * @see BaseValidator
- * @see Validator
- * @see IValidateRequired
- */
-public class ValidateUtil {
- private ValidateUtil() {
- throw new IllegalStateException("Utility class");
- }
-
- public static void validate(Object obj) {
- if (obj instanceof IValidateRequired) {
- ((IValidateRequired) obj).validate();
- }
- }
-
- public static void validate(T obj, BaseValidator validator) {
- validator.validate(obj);
- }
-}
diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/Validator.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/Validator.java
deleted file mode 100644
index b56ff50..0000000
--- a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/Validator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package xyz.zhouxy.plusone.validator;
-
-import java.util.function.Predicate;
-
-/**
- * 校验器
- *
- *
- * 可以使用以下方式初始化一个校验器:
- *
- *
- *
- * var validator = new Validator<Integer>()
- * .addRule(value -> Objects.nonNull(value), "value 不能为空")
- * .addRule(value -> (value >= 0 && value <= 500), "value 应在 [0, 500] 内");
- *
- *
- *
- * 然后通过校验器的 {@link #validate} 方法,或
- * {@link ValidateUtil#validate(Object, Validator)} 对指定对象进行校验。
- *
- *
- *
- * validator.validate(666);
- *
- *
- *
- * ValidateUtil.validate(255, validator);
- *
- *
- *
- * @author ZhouXY
- * @see IValidateRequired
- * @see ValidateUtil
- * @see BaseValidator
- */
-public final class Validator extends BaseValidator {
- public final Validator addRule(final Predicate rule, final String errorMessage) {
- withRule(rule, errorMessage);
- return this;
- }
-}
diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/validator2/BaseValidator2.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/validator2/BaseValidator2.java
deleted file mode 100644
index 257af16..0000000
--- a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/validator2/BaseValidator2.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package xyz.zhouxy.plusone.validator.validator2;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Function;
-
-public abstract class BaseValidator2 {
-
- private List> valueValidators = new ArrayList<>();
-
- protected final ValueValidator ruleFor(Function getter) {
- ValueValidator validValueHolder = new ValueValidator<>(getter);
- valueValidators.add(validValueHolder);
- return validValueHolder;
- }
-
- public void validate(T obj) {
- for (ValueValidator valueValidator : this.valueValidators) {
- valueValidator.validateProperty(obj);
- }
- }
-}
diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/validator2/ValueValidator.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/validator2/ValueValidator.java
deleted file mode 100644
index 933db5c..0000000
--- a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/validator/validator2/ValueValidator.java
+++ /dev/null
@@ -1,379 +0,0 @@
-package xyz.zhouxy.plusone.validator.validator2;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-
-import cn.hutool.core.util.StrUtil;
-import xyz.zhouxy.plusone.constant.RegexConsts;
-import xyz.zhouxy.plusone.exception.InvalidInputException;
-import xyz.zhouxy.plusone.util.RegexUtil;
-
-public class ValueValidator {
- Function getter;
- List> rules = new ArrayList<>();
-
- public ValueValidator(Function getter) {
- this.getter = getter;
- }
-
- private void withRule(Predicate condition,
- Function exceptionCreator) {
- withRule(value -> {
- if (!condition.test(value)) {
- throw exceptionCreator.apply(value);
- }
- });
- }
-
- private void withRule(Consumer rule) {
- this.rules.add(rule);
- }
-
- // ====================
- // ====== Object ======
- // ====================
-
- // ====== notNull =====
-
- public ValueValidator notNull() {
- return notNull("Value could not be null.");
- }
-
- public ValueValidator notNull(String errMsg) {
- return notNull(convertExceptionCreator(errMsg));
- }
-
- public ValueValidator notNull(Supplier exceptionCreator) {
- return notNull(convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator notNull(Function exceptionCreator) {
- withRule(Objects::nonNull, exceptionCreator);
- return this;
- }
-
- // ====== isNull =====
-
- public ValueValidator isNull(String errMsg) {
- return isNull(convertExceptionCreator(errMsg));
- }
-
- public ValueValidator isNull(Supplier exceptionCreator) {
- return isNull(convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator isNull(Function exceptionCreator) {
- withRule(Objects::isNull, exceptionCreator);
- return this;
- }
-
- // ===== equals =====
-
- public ValueValidator equalsThat(Object that) {
- return equalsThat(that, value -> new InvalidInputException(String.format("(%s) 必须与 (%s) 相等", value, that)));
- }
-
- public ValueValidator equalsThat(Object that, String errMsg) {
- return equalsThat(that, convertExceptionCreator(errMsg));
- }
-
- public ValueValidator equalsThat(
- Object that, Supplier exceptionCreator) {
- return equalsThat(that, convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator equalsThat(
- Object that, Function exceptionCreator) {
- withRule(value -> Objects.equals(value, that), exceptionCreator);
- return this;
- }
-
- // ===== state =====
-
- public ValueValidator state(Predicate condition) {
- return state(condition, "无效的用户输入");
- }
-
- public ValueValidator state(Predicate condition, String errMsg) {
- return state(condition, convertExceptionCreator(errMsg));
- }
-
- public ValueValidator state(
- Predicate condition,
- Supplier exceptionCreator) {
- return state(condition, convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator state(
- Predicate condition,
- Function exceptionCreator) {
- withRule(condition, exceptionCreator);
- return this;
- }
-
- // =================
- // ====== int ======
- // =================
-
- public ValueValidator between(int min, int max) {
- return between(min, max, String.format("数值不在 %s 和 %s 之间", String.valueOf(min), String.valueOf(max)));
- }
-
- public ValueValidator between(int min, int max, String errMsg) {
- return between(min, max, convertExceptionCreator(errMsg));
- }
-
- public ValueValidator between(int min, int max,
- Supplier exceptionCreator) {
- return between(min, max, convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator between(int min, int max,
- Function exceptionCreator) {
- withRule(value -> ((int) value >= min && (int) value < max), exceptionCreator);
- return this;
- }
-
- // ====================
- // ====== double ======
- // ====================
-
- public ValueValidator between(double min, double max) {
- return between(min, max, String.format("数值不在 %s 和 %s 之间", String.valueOf(min), String.valueOf(max)));
- }
-
- public ValueValidator between(double min, double max, String errMsg) {
- return between(min, max, convertExceptionCreator(errMsg));
- }
-
- public ValueValidator between(double min, double max,
- Supplier exceptionCreator) {
- return between(min, max, convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator between(double min, double max,
- Function exceptionCreator) {
- withRule(value -> ((double) value >= min && (double) value < max), exceptionCreator);
- return this;
- }
-
- // ================================
- // ====== Collection, String ======
- // ================================
-
- // ====== notEmpty =====
-
- public ValueValidator notEmpty(String errMsg) {
- return notEmpty(convertExceptionCreator(errMsg));
- }
-
- public ValueValidator notEmpty(Supplier exceptionCreator) {
- return notEmpty(convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator notEmpty(Function exceptionCreator) {
- withRule(value -> {
- if (value == null) {
- return false;
- }
- if (value instanceof Collection) {
- return !((Collection>) value).isEmpty();
- }
- if (value instanceof String) {
- return !((String) value).isEmpty();
- }
- return false;
- }, exceptionCreator);
- return this;
- }
-
- // ====== isEmpty =====
-
- public ValueValidator isEmpty(String errMsg) {
- return isEmpty(convertExceptionCreator(errMsg));
- }
-
- public ValueValidator isEmpty(Supplier exceptionCreator) {
- return isEmpty(convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator isEmpty(Function exceptionCreator) {
- withRule(value -> {
- if (value == null) {
- return false;
- }
- if (value instanceof Collection) {
- return ((Collection>) value).isEmpty();
- }
- if (value instanceof String) {
- return ((String) value).isEmpty();
- }
- return false;
- }, exceptionCreator);
- return this;
- }
-
- // =====================
- // ====== boolean ======
- // =====================
-
- // ====== isTrue ======
-
- public ValueValidator isTrue() {
- return isTrue("The value must be true.");
- }
-
- public ValueValidator isTrue(String errMsg) {
- return isTrue(convertExceptionCreator(errMsg));
- }
-
- public ValueValidator isTrue(Supplier exceptionCreator) {
- return isTrue(convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator isTrue(Function exceptionCreator) {
- withRule(Boolean.TRUE::equals, exceptionCreator);
- return this;
- }
-
- // ====== isFalse ======
-
- public ValueValidator isFalse() {
- return isFalse("The value must be false.");
- }
-
- public ValueValidator isFalse(String errMsg) {
- return isFalse(convertExceptionCreator(errMsg));
- }
-
- public ValueValidator isFalse(Supplier exceptionCreator) {
- return isFalse(convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator isFalse(Function exceptionCreator) {
- withRule(Boolean.FALSE::equals, exceptionCreator);
- return this;
- }
-
- // ====================
- // ====== String ======
- // ====================
-
- // ===== matches =====
-
- public ValueValidator matches(String regex, String errMsg) {
- return matches(regex, convertExceptionCreator(errMsg));
- }
-
- public ValueValidator matches(
- String regex,
- Supplier exceptionCreator) {
- return matches(regex, convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator matches(
- String regex,
- Function exceptionCreator) {
- withRule(input -> RegexUtil.matches((String) input, regex), exceptionCreator);
- return this;
- }
-
- // ===== matchesOr =====
-
- public ValueValidator matchesOr(String[] regexs, String errMsg) {
- return matchesOr(regexs, convertExceptionCreator(errMsg));
- }
-
- public ValueValidator matchesOr(
- String[] regexs,
- Supplier exceptionCreator) {
- return matchesOr(regexs, convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator matchesOr(
- String[] regexs,
- Function exceptionCreator) {
- withRule(input -> RegexUtil.matchesOr((String) input, regexs), exceptionCreator);
- return this;
- }
-
- // ===== matchesAnd =====
-
- public ValueValidator matchesAnd(String[] regexs, String errMsg) {
- return matchesAnd(regexs, convertExceptionCreator(errMsg));
- }
-
- public ValueValidator matchesAnd(
- String[] regexs,
- Supplier exceptionCreator) {
- return matchesAnd(regexs, convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator matchesAnd(
- String[] regexs,
- Function exceptionCreator) {
- withRule(input -> RegexUtil.matchesAnd((String) input, regexs), exceptionCreator);
- return this;
- }
-
- // ===== notBlank =====
-
- public ValueValidator notBlank() {
- return notBlank("This String argument must have text; it must not be null, empty, or blank");
- }
-
- public ValueValidator notBlank(String errMsg) {
- return notBlank(convertExceptionCreator(errMsg));
- }
-
- public ValueValidator notBlank(Supplier exceptionCreator) {
- return notBlank(convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator notBlank(Function exceptionCreator) {
- withRule(input -> StrUtil.isNotBlank((String) input), exceptionCreator);
- return this;
- }
-
- // ===== email =====
-
- public ValueValidator email() {
- return email("The value is not an email address.");
- }
-
- public ValueValidator email(String errMsg) {
- return email(convertExceptionCreator(errMsg));
- }
-
- public ValueValidator email(Supplier exceptionCreator) {
- return email(convertExceptionCreator(exceptionCreator));
- }
-
- public ValueValidator email(Function exceptionCreator) {
- return matches(RegexConsts.EMAIL, exceptionCreator);
- }
-
- // ========================================================================
-
- void validateProperty(DTO obj) {
- PROPERTY value = this.getter.apply(obj);
- for (var rule : this.rules) {
- rule.accept(value);
- }
- }
-
- private static Function convertExceptionCreator(String errMsg) {
- return convertExceptionCreator(errMsg);
- }
-
- private static Function convertExceptionCreator(
- Supplier exceptionSupplier) {
- return value -> exceptionSupplier.get();
- }
-}
diff --git a/plusone-system/plusone-system-application/src/main/java/xyz/zhouxy/plusone/system/application/common/util/PrincipalUtil.java b/plusone-system/plusone-system-application/src/main/java/xyz/zhouxy/plusone/system/application/common/util/PrincipalUtil.java
index 6e820f7..da05d59 100644
--- a/plusone-system/plusone-system-application/src/main/java/xyz/zhouxy/plusone/system/application/common/util/PrincipalUtil.java
+++ b/plusone-system/plusone-system-application/src/main/java/xyz/zhouxy/plusone/system/application/common/util/PrincipalUtil.java
@@ -2,11 +2,11 @@ package xyz.zhouxy.plusone.system.application.common.util;
import javax.annotation.Nullable;
-import xyz.zhouxy.plusone.exception.InvalidInputException;
import xyz.zhouxy.plusone.system.domain.model.account.Email;
import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
import xyz.zhouxy.plusone.system.domain.model.account.Principal;
import xyz.zhouxy.plusone.system.domain.model.account.Username;
+import xyz.zhouxy.plusone.validator.InvalidInputException;
/**
* 根据字面值,判断并生成 {@link Principal} 值对象。
diff --git a/plusone-system/plusone-system-application/src/main/java/xyz/zhouxy/plusone/system/application/exception/UnsupportedMenuTypeException.java b/plusone-system/plusone-system-application/src/main/java/xyz/zhouxy/plusone/system/application/exception/UnsupportedMenuTypeException.java
index 993d936..429246b 100644
--- a/plusone-system/plusone-system-application/src/main/java/xyz/zhouxy/plusone/system/application/exception/UnsupportedMenuTypeException.java
+++ b/plusone-system/plusone-system-application/src/main/java/xyz/zhouxy/plusone/system/application/exception/UnsupportedMenuTypeException.java
@@ -1,6 +1,6 @@
package xyz.zhouxy.plusone.system.application.exception;
-import xyz.zhouxy.plusone.exception.InvalidInputException;
+import xyz.zhouxy.plusone.validator.InvalidInputException;
public class UnsupportedMenuTypeException extends InvalidInputException {