0

Not sure what am I doing wrong - but after I submit the person form without any value
I am unable to see any validation error in the html output.


When I add a breakpoint in the controller I am able to see the "errors"
So it is going to result.hasErrors() tried to add * form:errors path="*" - still nothing
but still errors are not on the form.

Get method:
Person class is a POJO with no annotations.

@RequestMapping(value="/person/add" , method = RequestMethod.GET)
public ModelAndView personAdd() {       
    ModelAndView modelAndView = new ModelAndView("personAdd");
    Person person = new Person();
    person.setCreationDate(new Date());
    modelAndView.addObject(person);
    return modelAndView;
}

post method to save the new person

@RequestMapping(value="/person/add" , method = RequestMethod.POST)
public ModelAndView processSubmit(@ModelAttribute("person") Person person,BindingResult result) {

personValidator.validate(person, result);

if (result.hasErrors()) {
    ModelAndView modelAndView = new ModelAndView("personAdd");          
    modelAndView.addObject(person);         
    return modelAndView;
} else {
    ModelAndView modelAndView = new ModelAndView("refreshParent");                      
    dao.persist(person);            
    return modelAndView;
}
}   

The personValidator:

@Override
public void validate(Object target, Errors errors) {

    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "personName","required.personName", "Name is required.");

The Person form (for simplicity only name is there)

<form:form method="POST" modelAttribute="person" action="${pageContext.request.contextPath}/person/add">
<form:errors path="*" cssClass="errorblock" element="div"/>
<form:errors path="*" />
      <div class="form-group">
         <label class="control-label" for="inputError">Person Name:</label>  
        <form:input path="personName" class="form-control" placeholder="personName"/>
        <form:errors path="personName" cssClass="error" />
    </div>
<form:form>
JavaSheriff
  • 7,074
  • 20
  • 89
  • 159
  • What does personValidator look like? Have you tried using Spring MVC's integrated validation support using `@Valid` in association with `@ModelAttribute`? – geoand Jun 30 '14 at 06:07
  • added personValidator, to use @Valid i need to incorporate other annotations on my Person correct? – JavaSheriff Jun 30 '14 at 13:40
  • Yes that's exactly right! – geoand Jun 30 '14 at 13:48
  • Have you checked that your validator actually populates the `Errors` object? – geoand Jun 30 '14 at 13:49
  • Yes it does, I set a breakpoint in the code an I see it going into the rejectIfEmptyOrWhitespace – JavaSheriff Jun 30 '14 at 20:25
  • And what happens with the `Errors` object? Does it get populated with any errors? – geoand Jun 30 '14 at 20:31
  • this is the errors content: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'person' on field 'name': rejected value []; codes [required.name.person.name,required.name.name,required.name.java.lang.String,required.name]; arguments []; default message [Field Name is required.] – JavaSheriff Jul 01 '14 at 18:09
  • Would it be possible for you to share the project? – geoand Jul 03 '14 at 13:15

2 Answers2

3
ModelAndView modelAndView = new ModelAndView("personAdd");          

This line constructs a a new ModelAndView and by doing that you dismiss the current model. You add only the object in the line following this, but you have effectivly destroyed the binding results already available. If you use this construct pass in the model from the BindingResults. And you don't have to add the model object anymore as that is already included.

ModelAndView modelAndView = new ModelAndView("personAdd", result.getModel());          

However with the annotation driven @Controller you don't have to return a ModelAndView in this case a simple String would suffice.

@RequestMapping(value="/person/add" , method = RequestMethod.POST)
public ModelAndView processSubmit(@ModelAttribute("person") Person person,BindingResult result) {

    personValidator.validate(person, result);

    if (result.hasErrors()) {
        return "personAdd";
    } else {        
        dao.persist(person);            
        return "refreshParent";
    }
}   

This will render the correct view and leave the current model (which contains the errors) intact.

You could even apply automatic validation by adding @Valid to your model attribute argument and include a @InitBinder annotated method.

@RequestMapping(value="/person/add" , method = RequestMethod.POST)
public ModelAndView processSubmit(@Valid @ModelAttribute("person") Person person,BindingResult result) {

    if (result.hasErrors()) {
        return "personAdd";
    } else {        
        dao.persist(person);            
        return "refreshParent";
    }
}   

@InitBinder
public void initBinder(WebDataBinder dataBinder) {
    dataBinder.setValidator(personValidator);
}
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
1

Try to put this configuration:

@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) {

    if (result.hasErrors()) {
        return "petForm";
    }

    // ...

}

And put this in your person class

@NotNull
String personName;

And do not forget to place in your Spring XML file or the same but in your java configuration

<mvc:annotation-driven/>

All this will do the validation

nicearma
  • 750
  • 2
  • 8
  • 21