使用Java8创建验证框架

使用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

我正在用Java8开发一个伪验证框架

到目前为止,我所拥有的是这个接口,它是java中谓词接口的重写:

@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());


}