使用Java8创建验证框架
我正在用Java8开发一个伪验证框架 到目前为止,我所拥有的是这个接口,它是java中谓词接口的重写:使用Java8创建验证框架,java,java-8,predicate,Java,Java 8,Predicate,我正在用Java8开发一个伪验证框架 到目前为止,我所拥有的是这个接口,它是java中谓词接口的重写: @FunctionalInterface public interface Validation<K> { public GenericValidationResult test(K param); default Validation<K> and(Validation<K> other) { return (param) -> { Gene
@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);
};
}
}
假设此对象仅在假人的名字以s开头,姓氏以p开头且年龄大于20时才有效。目前,我无法使用我的框架执行此验证,我尝试创建此验证,但无效:
public static final <T> Validation<T> validateObject(Predicate<T> p) {
return GenericValidation.from(p);
}
我想让这个方法抽象,因为我不想只在虚拟对象上使用它,如果将来我创建一个汽车对象,我希望能够验证同一个汽车对象
我该怎么办 java 8中的泛型Util
编写一个类抽象验证器
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;
});
}
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);
}
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;
}
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);
}
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;
});
}
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);
}
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());
}