4

I always used @Valid and a BindingResult to validate form fields. Now using Ajax, based on this article, it's not possible to use BindingResult instead of or additional to HttpServletResponse because this would result in a Bad Request (HTTP Error Code 400).

How to validate my form fields now?

  @RequestMapping( value = "/save.html", params = "json", method = RequestMethod.POST )
  public @ResponseBody Map<String, ? extends Object> saveJSON( @RequestBody Location location, /* BindingResult result, */ HttpServletResponse response )
  {
    return Collections.singletonMap( "foo", "foobar" );
  }

This was the old way without ajax:

  @RequestMapping( value = "/save.html", method = RequestMethod.POST )
  public String save( @ModelAttribute( "location" ) @Valid Location location, BindingResult result, Map<String, Object> map )
  {
    Location l;
    if ( ( l = service.findByTitle( location.getTitle() ) ) != null )
    {
      if ( location.getId() != l.getId() )
      {
        result.addError( new FieldError( "location", "title", messageSource.getMessage( "Unique.location.title", null, null ) ) );
      }
    }

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

    service.save( location );
    return "redirect:/locations/index.html";
  }

EDIT

Tried this, but there's no errors member in result which contains true when leaving form unfilled (this should cause a @NotEmpty Constraint message)

  @RequestMapping( value = "/save.html", params = "json", method = RequestMethod.POST )
  public @ResponseBody Map<String, ? extends Object> saveJSON( @RequestBody Location location, HttpServletResponse response, Map<String, Object> map )
  {
    BindingResult result = new BeanPropertyBindingResult( location, "" );
    if ( result.hasErrors() ) map.put( "errors", true );
    map.put( "foo", "foobar" );
    return map;
  }
1
  • Which version of spring do you use 3.0 or 3.1? Commented Feb 12, 2012 at 19:17

1 Answer 1

2

Seems you are using hibernate validator. If so try this

in your Controller :

//other imports
import javax.validation.Validator;
@Controller()
class MyController{

    @autowire()
    @qualifier("myValidator")
    private Validator validator;
    public Validator getValidator() {
        return mValidator;
    }

    public void setValidator(Validator validator) {
        this.mValidator = validator;
    }

   @RequestMapping( value = "/save.html", params = "json", method = RequestMethod.POST )
   public @ResponseBody Map<String, ? extends Object> saveJSON( @RequestBody Location location, HttpServletResponse response )
   {
       Set<ConstraintViolation<Location>> errors = getValidator().validate(location);
       Map<String, String> validationMessages = new HashMap<String, String>();
       if(!errors.isEmpty())
       {
          //this map will contain the validation messages
          validationMessages = validationMessages(errors); 

          //probably you would like to send the errors back to client
          return validationMessages ;
       }
       else
       {
           //do whatever you like to do with the valid bean

       }
   }

   public Map<String, String> validationMessages(Set<ConstraintViolation<Location>> failures) {
        Map<String, String> failureMessages = new HashMap<String, String>();
        for (ConstraintViolation<Location> failure : failures) {

                failureMessages.put(failure.getPropertyPath().toString(), failure.getMessage());
        }
        return failureMessages;
    }



}

in your spring context file add the following bean

<beans:bean id="myValidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

hope it helps :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.