首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用java 8创建验证框架

使用java 8创建验证框架
EN

Stack Overflow用户
提问于 2020-02-01 07:50:52
回答 1查看 1.6K关注 0票数 0

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

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

代码语言:javascript
复制
@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);
};
}

该接口由下面的具体实现实现:

代码语言:javascript
复制
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表示的结果:

代码语言:javascript
复制
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);
}

这就是我的框架的基础。我创建了这个类:

代码语言:javascript
复制
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的对象:

代码语言:javascript
复制
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的情况下才有效。目前我无法在我的框架中执行此验证,我试图创建此验证,但它不起作用:

代码语言:javascript
复制
public static final <T> Validation<T> validateObject(Predicate<T> p) {
 return GenericValidation.from(p);                                  
}                                                                     

并使用相同的方法,如下所示:

代码语言:javascript
复制
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对象。

我该怎么办?

EN

回答 1

Stack Overflow用户

发布于 2020-10-01 01:17:11

java 8中的泛型Util

编写一个类AbstractValidator

代码语言:javascript
复制
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类

代码语言:javascript
复制
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测试用例

代码语言:javascript
复制
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());


}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60012735

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档