web-dev-qa-db-fra.com

Différence entre @Valid et @Validated in Spring

Spring prend en charge deux méthodes de validation différentes: la validation Spring et la validation du bean JSR-303. Les deux peuvent être utilisés en définissant un validateur Spring qui délègue à d'autres délégateurs, y compris le validateur de bean. Jusqu'ici tout va bien.

Mais quand annoter des méthodes pour demander réellement une validation, c'est une autre histoire. Je peux annoter comme ça

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

ou comme ça

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

Ici, @Valid est javax.validation.Valid , et @Validated est org.springframework.validation.annotation.Validated . Les docs pour ce dernier disent

Variante de JSR-303's Valid, prenant en charge la spécification de groupes de validation. Conçu pour une utilisation pratique avec la prise en charge de Spring JSR-303 mais pas spécifique à JSR-303.

ce qui n'aide pas beaucoup parce qu'il ne dit pas exactement en quoi c'est différent. Si du tout. Les deux semblent fonctionner assez bien pour moi.

74
Sergei Tachenov

Comme vous l'avez cité dans la documentation, @Validated a été ajouté pour prendre en charge les "groupes de validation", c'est-à-dire les groupes de champs du bean validé. Ceci peut être utilisé dans des formulaires en plusieurs étapes où vous pouvez valider le nom, le courrier électronique, etc. dans la première étape, puis d’autres champs dans les étapes suivantes.

La raison pour laquelle cela n'a pas été ajouté à l'annotation @Valid est qu'elle est normalisée à l'aide du processus de communauté Java (JSR-303), ce qui prend du temps et que les développeurs de Spring voulaient permettre aux utilisateurs de l'utiliser. cette fonctionnalité plus tôt.

Allez à ce billet jira pour voir comment l'annotation a vu le jour.

59
frant.hartm

Une réponse plus simple. Pour ceux qui ne savent toujours pas ce qu'est la Terre "groupe de validation" .

Utilisation de @Valid Validation

Manette:

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

Objet de formulaire:

public class Account {

    @NotBlank
    private String username;

    @Email
    @NotBlank
    private String email;

}

Utilisation de @Validated Groupe de validation
Source: http://blog.codeleak.pl/2014/08/validation-groups-in-spring-mvc.html

Manette:

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

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

Objet de formulaire:

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;

}
54
Zhu Hang

en plus de ce qui précède, vous ne pouvez appliquer que @Valid sur un domaine/champ pour une validation imbriquée, pas avec un @validated.

1
Zelin Zhu

Dans les exemples de fragments de code de la question, @Valid et @Validated ne font aucune différence. Mais si le @RequestBody est annoté avec un objet List ou s'il s'agit d'une valeur de chaîne annotée par @RequestParam, la validation ne prendra pas effet.

Nous pouvons utiliser la capacité de validation au niveau de la méthode de @Validated pour le faire fonctionner. Pour y parvenir, l’important est de placer @Validated sur la classe. Cela peut constituer une autre différence importante entre @Valid et @Validated dans le cadre printanier.

Référence

0
Lebecca