添加对 Map<String, Object> 的校验。

for-mfp
ZhouXY108 2023-11-03 00:51:49 +08:00
parent 0e2dc01cf7
commit 7a3801affe
3 changed files with 179 additions and 3 deletions

View File

@ -0,0 +1,87 @@
package xyz.zhouxy.plusone.validator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class MapValidator {
private final List<Consumer<Map<String, Object>>> rules = new ArrayList<>();
private final List<PropertyValidator<Map<String, Object>, ?, ?>> propertyValidators = new ArrayList<>();
protected void withRule(final Predicate<Map<String, Object>> rule, final String errorMessage) {
withRule(rule, () -> InvalidInputException.of(errorMessage));
}
protected <E extends RuntimeException> void withRule(Predicate<Map<String, Object>> rule, Supplier<E> exceptionBuilder) {
withRule(rule, value -> exceptionBuilder.get());
}
protected <E extends RuntimeException> void withRule(Predicate<Map<String, Object>> condition,
Function<Map<String, Object>, E> exceptionBuilder) {
withRule(value -> {
if (!condition.test(value)) {
throw exceptionBuilder.apply(value);
}
});
}
protected void withRule(Consumer<Map<String, Object>> rule) {
this.rules.add(rule);
}
protected final <R> ObjectValidator<Map<String, Object>, R> ruleFor(String key) {
ObjectValidator<Map<String, Object>, R> validValueHolder = new ObjectValidator<>(map -> (R) map.get(key));
propertyValidators.add(validValueHolder);
return validValueHolder;
}
protected final IntValidator<Map<String, Object>> ruleForInt(String key) {
IntValidator<Map<String, Object>> validValueHolder = new IntValidator<>(map -> map.get(key));
propertyValidators.add(validValueHolder);
return validValueHolder;
}
protected final DoubleValidator<Map<String, Object>> ruleForDouble(String key) {
DoubleValidator<Map<String, Object>> validValueHolder = new DoubleValidator<>(map -> map.get(key));
propertyValidators.add(validValueHolder);
return validValueHolder;
}
protected final BoolValidator<Map<String, Object>> ruleForBool(String key) {
BoolValidator<Map<String, Object>> validValueHolder = new BoolValidator<>(map -> map.get(key));
propertyValidators.add(validValueHolder);
return validValueHolder;
}
protected final StringValidator<Map<String, Object>> ruleForString(String key) {
StringValidator<Map<String, Object>> validValueHolder = new StringValidator<>(map -> map.get(key));
propertyValidators.add(validValueHolder);
return validValueHolder;
}
protected final <E> CollectionValidator<Map<String, Object>, E> ruleForCollection(String key) {
CollectionValidator<Map<String, Object>, E> validValueHolder = new CollectionValidator<>(m -> (Collection<E>) m.get(key));
propertyValidators.add(validValueHolder);
return validValueHolder;
}
public Map<String, Object> validate(Map<String, Object> obj, String... keys) {
for (Consumer<Map<String, Object>> rule : this.rules) {
rule.accept(obj);
}
for (PropertyValidator<Map<String, Object>, ?, ?> valueValidator : this.propertyValidators) {
valueValidator.validate(obj);
}
final Map<String, Object> result = new HashMap<>(keys.length);
for (String key : keys) {
result.put(key, obj.get(key));
}
return result;
}
}

View File

@ -0,0 +1,50 @@
package xyz.zhouxy.plusone.map;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.junit.jupiter.api.Test;
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
import xyz.zhouxy.plusone.validator.MapValidator;
class MapValidatorTests {
@Test
void testMapValidator() {
Map<String, Object> params = new HashMap<>();
params.put("username", "ZhouXY");
params.put("admin", true);
params.put("password", "99Code108");
params.put("password2", "99Code108");
params.put("test", "88gggg");
params.put("roles", Arrays.asList("admin", "ZhongShanAdmin"));
params = RegisterParamsValidator.INSTANCE
.validate(params, "roles", "username", "admin", "password");
System.out.println(params);
}
}
class RegisterParamsValidator extends MapValidator {
RegisterParamsValidator() {
this.<List<String>>ruleFor("roles")
.notNull(() -> new NullPointerException("roles"));
this.ruleForString("username")
.matches(PatternConsts.USERNAME, "用户名不符合条件!");
this.ruleForBool("admin")
.notNull("admin could not be null.")
.isTrue("admin must be true.");
this.ruleForString("password")
.notBlank("密码不能为空!")
.matches(PatternConsts.PASSWORD, "密码格式错误!");
this.ruleForCollection("roles")
.notEmpty("角色列表不能为空!");
this.withRule(m -> Objects.equals(m.get("password"), m.get("password2")),
"两次输入的密码不一样!");
}
static final RegisterParamsValidator INSTANCE = new RegisterParamsValidator();
}

View File

@ -2,9 +2,7 @@ package xyz.zhouxy.plusone.validator2.test;
import static xyz.zhouxy.plusone.commons.constant.PatternConsts.*; import static xyz.zhouxy.plusone.commons.constant.PatternConsts.*;
import java.util.Arrays; import java.util.*;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -61,6 +59,47 @@ class ValidatorTests {
registerCommandValidator.validate(registerCommand); registerCommandValidator.validate(registerCommand);
System.out.println(registerCommand); System.out.println(registerCommand);
} }
@Test
void testValidateMap() {
Map<String, Object> params = new HashMap<>();
params.put("username", "zhouxy");
params.put("account", "zhouxy@code108.cn");
params.put("password", "89wy7G78gu7ggahB2");
params.put("age", 25);
params.put("roles", Arrays.asList("", "admin"));
Validator<Map<String, Object>> registerCommandValidator = new Validator<Map<String, Object>>()
// 传入 predicate 和 Function<T, E extends RuntimeException>
.addRule(command -> {
String username = (String) command.get("username");
return Objects.nonNull(username)
&& StringUtils.isNotEmpty(username)
&& StringUtils.isNotBlank(username)
&& RegexUtil.matches(username, USERNAME);
}, command -> new IllegalArgumentException(String.format("用户名【%s】不符合规范", command.get("username"))))
// 传入 predicate 和 error message
.addRule(command -> Predicates
.<String>of(Objects::nonNull)
.and(account -> RegexUtil.matchesOne(account, new Pattern[] { EMAIL, MOBILE_PHONE }))
.test((String) command.get("account")),
"请输入邮箱地址或手机号")
// 传入 rule
.addRule(command -> {
String password = (String) command.get("password");
Preconditions.checkArgument(StringUtils.isNotEmpty(password), "密码不能为空");
Preconditions.checkArgument(RegexUtil.matches(password, PASSWORD), "密码不符合规范");
})
// 传入 predicate 和 Supplier<E extends RuntimeException>
.addRule(command -> MoreCollections.isNotEmpty((List<String>) command.get("roles")),
() -> new RuntimeException("角色列表不能为空"))
.addRule(command -> {
Integer age = (Integer) command.get("age");
Preconditions.checkNotNull(age);
Preconditions.checkArgument(18 < age && 60 >= age);
});
registerCommandValidator.validate(params);
System.out.println(params);
}
} }
/** /**