Reputation: 2075
I have a simple MVC controller that takes a list of emails, and will then send a message to those emails.
{"emailAddresses" : []}
@RequestMapping(value = "/{id}/share", method = RequestMethod.POST)
@ResponseBody
public void shareThing(@PathVariable(value = "id") final String id, @Valid @NotEmpty @RequestBody final List<String> emailAddresses)
Basically, I want to use jsr-303 so that if the client posts a request with no emails, it fails. Preferably with a 401.
Should the above code work? Or what do I need to do? Here's the setup. Hibernate validator is on the classpath, so it should be picking up. However if I post an empty json array, it goes straight into the method with an empty array list as the bound parameter.
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.package.thing"})
public class WeConfiguration extends WebMvcConfigurerAdapter
{"emailAddresses" : []}
@RequestMapping(value = "/{id}/share", method = RequestMethod.POST)
@ResponseBody
public void shareThing(@PathVariable(value = "id") final String id, @Valid @NotEmpty @RequestBody final List<String> emailAddresses, BindingResult bindingResult)
{
System.out.println("Has Errors? " + bindingResult.hasErrors();
}
Has Errors? false
public class EmailListDTO {
@NotEmpty
private List<String> emailAddresses;
public List<String> getEmailAddresses() {
return emailAddresses;
}
public void setEmailAddresses(List<String> emailAddresses) {
this.emailAddresses = emailAddresses;
}
}
@RequestMapping(value = "/{id}/share", method = RequestMethod.POST)
@ResponseBody
public void shareThing(@PathVariable(value = "id") final String id, @Valid @RequestBody EmailListDTO emailListDTO, BindingResult bindingResult)
{
System.out.println("Has Errors? " + bindingResult.hasErrors();
}
{"emailAddresses" : []}
Has Errors? true
Upvotes: 2
Views: 5029
Reputation: 279970
@Valid
validates if the parameter class type itself has javax.validation
annotations on fields. So it would use the Validator
to scan the List
class for validation annotations, which is not what you want.
You should wrap your List<String>
into a DTO and change your parameter to that
public class MyListDTO {
@NotEmpty
private List<String> emailAddresses;
... //getters and setters
}
@Valid
doesn't just make it fail, it binds the error to a BindingResult
object. If you add add a BindingResult
parameter to your handler method (it must be next to your @Valid
parameter)
public void shareThing(@PathVariable(value = "id") final String id, @Valid @RequestBody final MyListDTO myDTO, BindingResult errors )
you can then checks the BindingResult
for errors and choose what to do.
Upvotes: 5