Java – Difference between @Valid and @Validated in Spring

javaspringspring-mvcvalidation

Spring supports two different validation methods: Spring validation and JSR-303 bean validation. Both can be used by defining a Spring validator that delegates to other delegators including the bean validator. So far so good.

But when annotating methods to actually request validation, it's another story. I can annotate like this

@RequestMapping(value = "/object", method = RequestMethod.POST)
public @ResponseBody TestObject create(@Valid @RequestBody TestObject obj, BindingResult result) {

or like this

@RequestMapping(value = "/object", method = RequestMethod.POST)
public @ResponseBody TestObject create(@Validated @RequestBody TestObject obj, BindingResult result) {

Here, @Valid is javax.validation.Valid, and @Validated is org.springframework.validation.annotation.Validated. The docs for the latter say

Variant of JSR-303's Valid, supporting the specification of validation
groups. Designed for convenient use with Spring's JSR-303 support but
not JSR-303 specific.

which doesn't help much because it doesn't tell exactly how it's different. If at all. Both seem to be working pretty fine for me.

Best Answer

A more straight forward answer. For those who still don't know what on earth is "validation group".

Usage for @Valid Validation

Controller:

@RequestMapping(value = "createAccount")
public String stepOne(@Valid Account account) {...}

Form object:

public class Account {

    @NotBlank
    private String username;

    @Email
    @NotBlank
    private String email;

}

Usage for @Validated Validation Group
Source: http://blog.codeleak.pl/2014/08/validation-groups-in-spring-mvc.html

Controller:

@RequestMapping(value = "stepOne")
public String stepOne(@Validated(Account.ValidationStepOne.class) Account account) {...}

@RequestMapping(value = "stepTwo")
public String stepTwo(@Validated(Account.ValidationStepTwo.class) Account account) {...}

Form object:

public class Account {

    @NotBlank(groups = {ValidationStepOne.class})
    private String username;

    @Email(groups = {ValidationStepOne.class})
    @NotBlank(groups = {ValidationStepOne.class})
    private String email;

    @NotBlank(groups = {ValidationStepTwo.class})
    @StrongPassword(groups = {ValidationStepTwo.class})
    private String password;

    @NotBlank(groups = {ValidationStepTwo.class})
    private String confirmedPassword;

}