Announcement Announcement Module
Collapse
No announcement yet.
ValidationUtils.invokeValidator: How to set property name on the validated object ? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ValidationUtils.invokeValidator: How to set property name on the validated object ?

    Hi all,

    I have a command object looking like this:

    Code:
    class Event {
        Date date;
        Person manager;
        List<Person> people;
    }
    and here is an Event validator exemple


    Code:
    public void validate(Object command, Errors errors) {
        LOGGER.debug("validating...");
        Event event = (Event) command;
       ValidationUtils.rejectIfEmptyOrWhitespace(errors, "date", "error.evennt.date.empty");
    		}
    }
    and a PersonValidator example:
    Code:
    public void validate(Object command, Errors errors) {
        LOGGER.debug("validating...");
        Person person = (Person) command;
       ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "error.person.name.empty);
    		}
    }
    This is a simplified example, just to expose the problem. In reality, my Person class is used in a lot of Controller, and has to be validated in several ways depending some parameters.

    My problem is that I want to validate my Event using a validator, and then invoking a validator for Person, and all the Person in my people list, then display these errors on my form.

    Is there a clean way to invoke the PersonValidator from the event validator passing him a prefix (in my previous case it has to be "manager.name" or "manager" in fact, to ensure that the errors object will be populated with the complete properties names ?

    I'am not sure to be clear enough
    What I can do now is this:
    Code:
    public void validate(Object command, Errors errors) {
        LOGGER.debug("validating...");
        Event event = (Event) command;
       ValidationUtils.rejectIfEmptyOrWhitespace(errors, "date", "error.event.date.empty");
       PersonValidator pv = new PersonValidator();
       ValidationUtils.invokeValidator(pv, event.getManager(), errors);
    
    		}
    }


    and What I want to be done is this:
    Last line is important: MyValidationUtils.invokeValidator takes an additional parameter.
    Code:
    public void validate(Object command, Errors errors) {
        LOGGER.debug("validating...");
        Event event = (Event) command;
       ValidationUtils.rejectIfEmptyOrWhitespace(errors, "date", "error.event.date.empty");
       PersonValidator pv = new PersonValidator();
       MyValidationUtils.invokeValidator(pv, event.getManager(), errors, "manager");
    
    		}
    }
    And I was wondering why this is not default in SpringMVC ?

    Please comment !

  • #2
    Hi,

    You have to use nesting if your command objects have custom objects to ensure reusability.

    1. have a property in the EventValidator whose type is Validator.
    2. inject the Person Validator via Spring into the Event Validator
    3. in the validate method do the following
    public class EventValidator implements Validator
    {
    // have a setter and getter for the personValidator
    private Validator personValidator;

    // return true if the class is assignable from Event.class
    .... boolean Supports(Class clazz){}

    public void validate(Object target, Errors errors)
    {
    Event vo = (Event)target;
    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "date", "error.event.date.empty");
    // in the jsp if you are using the form tag use the path as manager.property
    errors.pushNestedPath("manager");// this is the reference variable that you are using the Event class
    // use the getMethod to get the validator and call validate and pass the Person Object from the Event object to it.
    getPersonValidator().validate(vo.getPerson(),error s);
    errors.popNestedPath();

    }
    }

    Do not forget to pop and push else it wont work!!!

    Comment


    • #3
      Thank you !

      Code:
      errors.pushNestedPath("manager");// this is the reference variable that you are using the Event class
      // use the getMethod to get the validator and call validate and pass the Person Object from the Event object to it.
      getPersonValidator().validate(vo.getPerson(),error s);
      errors.popNestedPath();
      pushNestedPath and popNestedPath were my missing links . I can see clearly now.

      Comment


      • #4
        Hi all,


        another question about subject:
        How can I determnine if one of my Person List has errors ?

        I tried:
        Code:
        errors.hasFieldErrors("people[" + i + "]")) ;
        But this does not seem to work, even if I do it before the pop or after.
        Code:
        errors.hasErrors() ;
        always works, but, if I have an error on my manager and no errors on people, the result will not be accurate.

        Does some one have an idea ?

        thanks in advance.

        Comment


        • #5
          Hi all,

          self reply:

          I did it with:
          Code:
          BindException childrenErrors= new BindException(command, errors.getObjectName());
          childrenErrors.pushNestedPath("children");
          ValidationUtils.invokeValidator(childrenValidator, command, childrenErrors);
          childrenErrors.popNestedPath();
          if (childrenErrors.hasErrors()) {
              errors.reject("children", "children.has.errors");
              errors.addAllErrors(childrenErrors);
          }

          Comment

          Working...
          X