Difference between @Valid and @Validated in Spring

JavaSpringValidationSpring Mvc

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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

Solution 2 - Java

As you quoted from the documentation, @Validated was added to support "validation groups", i.e. group of fields in the validated bean. This can be used in multi step forms where you may validate name, email, etc.. in first step and then other fields in following step(s).

The reason why this wasn't added into @Valid annotation is because that it is standardized using the java community process (JSR-303), which takes time and Spring developers wanted to allow people to use this functionality sooner.

Go to this jira ticket to see how the annotation came into existence.

Solution 3 - Java

In the example code snippets of the question, @Valid and @Validated make no difference. But if the @RequestBody is annotated with a List object, or is a string value annotated by @RequestParam, the validation will not take effect.

We can use the @Validated's method-level validation capability to make it work. To achieve this, the key point is to place @Validated on the class. This may be another important difference between @Valid and @Validated in spring framework.

Refrence

Solution 4 - Java

besides above, you can only apply @Valid on a domain/field for nested validation, not with a @validated.

Solution 5 - Java

@Validated can be used for a class:

@Validated
public class Person {
    @Size(min=3)
    private String name;
...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSergei TachenovView Question on Stackoverflow
Solution 1 - Javazhuhang.jasperView Answer on Stackoverflow
Solution 2 - JavaFrantišek HartmanView Answer on Stackoverflow
Solution 3 - JavaLebeccaView Answer on Stackoverflow
Solution 4 - JavaZelin ZhuView Answer on Stackoverflow
Solution 5 - JavaDeqingView Answer on Stackoverflow