I have a Spring 3.2 application and I've created a REST API following this example based on Spring MVC. Now I am experiencing some issues while trying to validate some data for different http methods (e.g.: POST and PUT methods).
This would be a pretty simplified example:
public class myItem{
@NotEmpty
private String foo;
@NotEmpty
private String bar;
public myItem(String foo){
this.foo = foo;
this.bar = "";
}
public myItem(String foo, String bar){
this.foo = foo;
this.bar = bar;
}
/* getters & setters omitted */
}
This POJO is reused in the different request methods.
This would be my simplified controller:
@Controller
@RequestMapping("/api/item")
public class myItemController{
@RequestMapping(value="/", method=RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public @ResponseBody myItem createItem(@Valid @RequestBody myItem item){
/* do some stuff */
return item; //inserted item returned
}
@RequestMapping(value="/", method=RequestMethod.PUT)
@ResponseStatus(HttpStatus.NO_CONTENT)
public @ResponseBody myItem createItem(@Valid @RequestBody myItem item){
/* do some stuff */
return item //updated item returned
}
}
In the POST method I only expect foo field to be set, so this request would fail with the before above annotations. In the PUT method I expect both foo and bar fields to be set, so this request would be completed successfully.
What is the correct approach to deal with this kind of situations: in a certain request method you don't expect all fields to be filled up (some fields may have default values, hence you don't want to check all them, aka create), and in another method you must check all the fields (aka update).
Use validation groups:
public interface ValidateOnCreate {}
public interface ValidateOnUpdate {}
.
public class myItem{
@NotEmpty(groups = { ValidateOnCreate.class, ValidateOnUpdate.class })
private String foo;
@NotEmpty(groups = ValidateOnUpdate.class)
private String bar;
...
}
.
@RequestMapping(value="/", method=RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public @ResponseBody myItem createItem(
@Validated(ValidateOnCreate.class) @RequestBody myItem item) { ... }
@RequestMapping(value="/", method=RequestMethod.PUT)
@ResponseStatus(HttpStatus.NO_CONTENT)
public @ResponseBody myItem createItem(
@Validated(ValidateOnUpdate.class) @RequestBody myItem item) { ... }
Note that you need Spring-specific @Validated
in this case, because @Valid
doesn't allow you to specify groups.
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With