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;
}