我正在用java8开发一个伪验证框架。
到目前为止,我拥有的是这个接口,它是java中Predicate接口的重写:
@FunctionalInterface
public interface Validation<K> {
public GenericValidationResult test(K param);
default Validation<K> and(Validation<K> other) {
return (param) -> {
GenericValidationResult result = this.test(param);
return !result.isValid() ? result : other.test(param);
};
}
default Validation<K> or(Validation<K> other) {
return (param) -> {
GenericValidationResult result = this.test(param);
return result.isValid() ? result : other.test(param);
};
}该接口由下面的具体实现实现:
public class GenericValidation<K> implements Validation<K> {
private Predicate<K> predicate;
public static <K> GenericValidation<K> from(Predicate<K> predicate) {
return new GenericValidation<K>(predicate);
}
private GenericValidation(Predicate<K> predicate) {
this.predicate = predicate;
}
@Override
public GenericValidationResult test(K param) {
return predicate.test(param) ? GenericValidationResult.ok() : GenericValidationResult.fail();
}它的职责是执行某个条件的谓词,并创建由GenericValidationResult表示的结果:
public class GenericValidationResult {
private boolean valid;
public boolean isValid() {
return valid;
}
public static GenericValidationResult ok() {
return new GenericValidationResult(true);
}
private GenericValidationResult(boolean valid) {
this.valid = valid;
}
public static GenericValidationResult fail() {
return new GenericValidationResult(false);
}
public Optional<String> getFieldNameIfInvalid(String field) {
return this.valid ? Optional.empty() : Optional.of(field);
}这就是我的框架的基础。我创建了这个类:
public class ValidatorUtil {
public static final Validation<String> notNullString = GenericValidation.from(s -> s != null);
public static final Validation<Object> notNullObject = GenericValidation.from(s -> s != null);
public static final Validation<String> notEmptyString = GenericValidation.from(s -> !s.isEmpty());
public static final Validation<Integer> notNullInteger = GenericValidation.from(s -> s != null);
public static final Validation<Integer> greaterThanZero = GenericValidation.from(s -> s > 0);
public static final Validation<List> notEmptyList = GenericValidation.from(s -> s != null && !s.isEmpty());
public static final Validation<Enum> notNullEnum = GenericValidation.from(s -> s != null);
public static final Validation<String> stringMoreThan(int size) {
return GenericValidation.from(s -> ((String) s).length() > size);
};
public static final Validation<String> stringLessThan(int size) {
return GenericValidation.from(s -> ((String) s).length() < size);
};
public static final Validation<String> stringBetween(int morethan, int lessThan) {
return stringMoreThan(morethan).and(stringLessThan(lessThan));
};
public static final Validation<Integer> integerMoreThan(int limit) {
return GenericValidation.from(s -> s > limit);
};
public static final Validation<Integer> integerLessThan(int size) {
return GenericValidation.from(s -> s < size);
};
public static final Validation<Integer> integerBetween(int morethan, int lessThan) {
return integerMoreThan(morethan).and(integerLessThan(lessThan));
}; 这就是目前我的框架所支持的所有验证。我现在要做的是创建一个通用的验证。基本上,我创建了一个名为dummy的对象:
public class Dummy {
private String firstName;
private String lastName;
private String email;
private Integer age;
public Dummy() {
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}}
假设这个对象只有在虚拟对象的名字以S开头,姓氏以P开头,年龄大于20的情况下才有效。目前我无法在我的框架中执行此验证,我试图创建此验证,但它不起作用:
public static final <T> Validation<T> validateObject(Predicate<T> p) {
return GenericValidation.from(p);
} 并使用相同的方法,如下所示:
private static boolean test(Employee e) {
return ValidatorUtil.validateObject(em -> em.getFirstName().startsWith("S") && em.getLastName().startsWith("P") && em.getAge() > 20).test(e);
}
public static void main(String[] args) {
Employee e = new Employee();
e.setAge(123);
e.setEmail("email");
e.setFirstName("firstName");
e.setLastName("lastName");
test(e);
}我想让这个方法成为抽象的,因为我不想只在虚拟对象上使用它,如果将来我创建了一个Car对象,我希望能够验证相同的car对象。
我该怎么办?
发布于 2020-10-01 01:17:11
java 8中的泛型Util
编写一个类AbstractValidator
public abstract class AbstractValidator {
private Map<Predicate, String> validatorMap = new HashMap<>();
protected List<String> messages;
public AbstractValidator() {
this.messages = new ArrayList<>();
}
protected <E> AbstractValidator add(Predicate<E> predicate, String reason) {
validatorMap.put(predicate, reason);
return this;
}
protected AbstractValidator apply(String fieldName, Object val) {
this.validatorMap.forEach((modifier, reason) -> {
if (!modifier.test(val)) {
String message = MessageFormat.format("{0} {1}", fieldName, reason);
messages.add(message);
}
});
this.validatorMap.clear();
return this;
}
public void end() {
Optional.ofNullable(messages).filter(CollectionUtils::isEmpty)
.orElseThrow(() -> {
RuntimeException businessException = new RuntimeException( messages);
messages.clear();
return businessException;
});
}实现AbstractValidator的GenericValidator类
public class GenericValidator extends AbstractValidator {
private GenericValidator() {
super();
}
public static GenericValidator of() {
return new GenericValidator();
}
public GenericValidator nonNull() {
add(Objects::nonNull, "Field value is null");
return this;
}
public GenericValidator isNotEmpty() {
add(StringUtils::isNotEmpty, "Field is empty");
return this;
}
public GenericValidator min(int min) {
add(s -> ((String) s).length() >= min, "Field min size is " + min);
return this;
}
public GenericValidator max(int max) {
add(s -> ((String) s).length() <= max, "Field max size is " + max);
return this;
}
public GenericValidator apply(String fieldName, Object val) {
return (GenericValidator) super.apply(fieldName, val);
}junit测试用例
class GenericValidatorTest {
@Test
void genericValidation() {
Fulfillment input = Fulfillment.builder().fulfillmentId(UUID.randomUUID().toString()).fulfillmentStatus(FulfillmentStatus.CREATED)
.build();
GenericValidator of = GenericValidator.of();
of.nonNull().apply("fulfillment", input).end();
of.nonNull().apply("fulfillmentStatus", input.getFulfillmentStatus())
.isNotEmpty().min(36).max(36).apply("fulfillmentId", input.getFulfillmentId()).end();
}
@Test
void genericValidationWithExceptionInput() {
Fulfillment input = Fulfillment.builder().fulfillmentId(UUID.randomUUID().toString()).fulfillmentStatus(FulfillmentStatus.CANCELLED)
.build();
GenericValidator validator = GenericValidator.of()
.nonNull().apply("fulfillment", input)
.nonNull().apply("fulfillmentStatus", input.getFulfillmentStatus())
.isNotEmpty().min(37).max(35).apply("fulfillmentId", input.getFulfillmentId());
Assert.assertThrows(RuntimeException.class, () -> validator.end());
}https://stackoverflow.com/questions/60012735
复制相似问题