Java - 特定验证错误

时间:2013-10-09 23:01:33

标签: java coding-style

我想验证一个名为Person的类。我可以这样写:

class Person {
  ...
  public boolean isValid() {
    return (name != null && age > 0);
  }
}

但是,在我的表示层中,我想向用户显示验证失败原因的具体原因。

我提出的解决方案是:

  1. 在特定于错误的isValid()内抛出异常
  2. isValid()返回PersonValidationError枚举而不是布尔值
  3. 复制表示层中的验证逻辑
  4. 我想知道处理这个的最佳方法是什么。另外,Java标准库如何处理这种情况?

4 个答案:

答案 0 :(得分:2)

我不知道你在用什么。我习惯了Spring MVC项目。 在这些上,您可以使用JSR-303验证器,它将使用对象上的所有错误填充ObjectErros对象。

如果您使用的是spring,请尝试寻找SmartValidator。注入后,您可以执行以下操作:

BeanPropertyErrors br = new BeanPropertyErros();
validator.validate(object,br);

如果您没有使用Spring,请尝试寻找JSR-303实现。

有了它,你可以在要验证的类的字段上使用@ NotEmpty,@ NotNull,@ Min,@ Length。

答案 1 :(得分:1)

  1. 从bool函数抛出异常不是一个好方法
  2. 如果name为null且age为< 0?
  3. ,则返回什么
  4. 有时可以是一个解决方案,但在这种情况下不是
  5. 我提出的建议如下:

    class Person {
    ...
    private boolean isValidated = false;
    private ArrayList<String> validationErrors = new ArrayList<String>();
    private void validate()
    {
        validationErrors.clear();
        if (name == null)
            validationErrors.add("Incorrect name");
        if (age < 0)
            validationErrors.add("Incorrect age");
        isValidated = true;
    }
    public boolean isValid()
    {
        if (!isValidated)
            validate();
        return (validationErrors.size()==0);
    }
    public ArrayList<String> getValidationErors()
    {
        if (!isValidated)
            validate();
        return validationErrors;
    }
    

答案 2 :(得分:1)

在提出我的解决方案之前的几点:

  1. 例外情况应该用于或多或少的例外条件。 根据您的说法,用户提交的内容并不少见 错误的数据。

  2. 当您的Person班级增长时,您将添加越来越多必须满足的条件才能使其生效。

  3. 除了例外,您一次只能显示一个错误,如果提交的数据有多个错误怎么办?

  4. 将验证方法放入Person课程似乎不对。例如,如果您希望在应用中的不同位置使用不同的验证政策,该怎么办?

  5. 所以,我会让你的Person类免于验证逻辑:

    class Person {
    
        final String name;
        final int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    

    然后实现一些带人并且验证它的类。我们的想法是拥有不同的验证器,每个验证器都有自己的验证规则和自己的验证消息。 enum很高兴实现这一目标:

    enum Validator {
    
        NOT_NULL_NAME("Name must not be null") {
            @Override
            public boolean validate(Person person) {
                return person.name != null;
            }
        },
        AGE_GREATER_THAN_ZERO("Age must be greater than zero") {
            @Override
            public boolean validate(Person person) {
                return person.age > 0;
            }
        };
    
        final String errorMessage;
    
        private Validator(String errorMessage) {
            this.errorMessage = errorMessage;
        }
    
        public abstract boolean validate(Person person);
    }
    

    看看用不同的消息添加一些新条件有多容易?只是另一个枚举实例。

    现在创建一个验证人员的课程。它只是遍历所有验证器并收集错误消息。

    class PersonValidator {
    
        private final List<String> errors = new ArrayList<String>();
    
        public PersonValidator(Person person) {
            for (Validator validator : Validator.values()) {
                if (!validator.validate(person)) {
                    errors.add(validator.errorMessage);
                }
            }
        }
    
        public boolean isValid() {
            return errors.isEmpty();
        }
    
        public Collection<String> getErrors() {
            return errors;
        }
    }
    

    如何使用它的示例:

    public static void main(String... args) {
        Person[] people = { new Person(null, 0), 
                             new Person(null, 42), 
                             new Person("Joe", 0), 
                             new Person("Joe", 42) };
        for (int i = 0; i < people.length; i++) {
            PersonValidator validator = new PersonValidator(people[i]);
            System.out.println(String.format("Person no %s is %s valid. %s", 
                  i, 
                  validator.isValid() ? "" : "not", 
                  Joiner.on(", ").join(validator.getErrors())));
    
        }
    }
    

    以上版画:

    Person no 0 is not valid. Name must not be null, Age must be greater than zero
    Person no 1 is not valid. Name must not be null
    Person no 2 is not valid. Age must be greater than zero
    Person no 3 is  valid. 
    

    非常整洁,呵呵?

答案 3 :(得分:0)

我现在已经解决了以下问题:

class Person {
  ...
  public void validate() throws ValidationException {
    if(name == null) {
      throw ValidationException("Name cannot be null");
    }

    if(age < 0) {
      throw ValidationException("Age cannot be less than 0");
    }
  }
}

然后在我的表示层中,我可以执行以下操作:

try {
  myPerson.validate();
} catch(ValidationException e) {
  errorMessage = "Invalid person: " + e.getMessage();
}