Dans l'exemple suivant, le ScriptFile
paramètre est marqué d'une @Valid
annotation.
Que fait l' @Valid
annotation?
@RequestMapping(value = "/scriptfile", method = RequestMethod.POST)
public String create(@Valid ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {
if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");
if (result.hasErrors()) {
modelMap.addAttribute("scriptFile", scriptFile);
modelMap.addAttribute("showcases", ShowCase.findAllShowCases());
return "scriptfile/create";
}
scriptFile.persist();
return "redirect:/scriptfile/" + scriptFile.getId();
}
la source
@Valid
leApplicationForm
paramètre mais les validations étaient toujours déclenchées surdate
lenull
champ (défini comme ). S'il vous plaît, expliquez.IIRC @Valid n'est pas une annotation Spring mais une annotation JSR-303 (qui est le standard de validation de Bean). En gros, il vérifie si les données que vous envoyez à la méthode sont valides ou non (il validera le scriptFile pour vous).
la source
@Valid
en soi n'a rien à voir avec le printemps. Cela fait partie de la spécification Bean Validation (il y en a plusieurs, le dernier étant le JSR 380 au second semestre 2017), mais il@Valid
est très ancien et dérive entièrement de JSR 303.Comme nous le savons tous, Spring est très efficace pour intégrer toutes les bibliothèques JSR et java en général (pensez à JPA, JTA, Caching, etc.) et bien sûr, ces gars-là se sont également occupés de la validation. L'un des composants clés qui facilite cela est MethodValidationPostProcessor .
Essayer de répondre à votre question
@Valid
est très pratique pour ce que l'on appelle la validation en cascade lorsque vous souhaitez valider un graphique complexe et pas seulement des éléments de premier niveau d'un objet. Chaque fois que vous voulez aller plus loin, vous devez utiliser@Valid
. C'est ce que dicte JSR. Spring se conformera à cela avec quelques écarts mineurs (par exemple, j'ai essayé de mettre à la@Validated
place de la@Valid
méthode RestController et la validation fonctionne, mais la même chose ne s'appliquera pas pour un beans "service" réguliers).la source
ScriptFile scriptFile
.public String create(@Valid @NotNull ScriptFile scriptFile, BindingResult result, ModelMap modelMap) { if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");
Je suppose que cette
@NotNull
annotation est valide si la condition n'est pas nécessaire.la source
En ajoutant simplement à la réponse ci-dessus, dans une application Web
@valid
est utilisée où le bean à valider est également annoté avec des annotations de validation@NotNull
, par exemple@Email
(annotation d'hibernation), donc lors de l'obtention de l'entrée de l'utilisateur, les valeurs peuvent être validées et le résultat de la liaison aura la validation résultats.bindingResult.hasErrors()
dira si une validation a échoué.la source
Un autre aspect pratique de @Valid non mentionné ci-dessus est que (c'est-à-dire en utilisant Postman pour tester un point de terminaison) @Valid formatera la sortie d'un appel REST incorrect en JSON formaté au lieu d'un blob de texte à peine lisible. Ceci est très utile si vous créez une API commercialement consommable pour vos utilisateurs.
la source
Je pense savoir où va votre question. Et comme cette question est celle qui apparaît dans les principaux résultats de recherche de Google, je peux donner une réponse claire sur ce que fait l'annotation @Valid.
Je vais présenter 3 scénarios sur la façon dont j'ai utilisé @Valid
Modèle:
public class Employee{ private String name; @NotNull(message="cannot be null") @Size(min=1, message="cannot be blank") private String lastName; //Getters and Setters for both fields. //... }
JSP:
... <form:form action="processForm" modelAttribute="employee"> <form:input type="text" path="name"/> <br> <form:input type="text" path="lastName"/> <form:errors path="lastName"/> <input type="submit" value="Submit"/> </form:form> ...
Contrôleur pour le scénario 1:
@RequestMapping("processForm") public String processFormData(@Valid @ModelAttribute("employee") Employee employee){ return "employee-confirmation-page"; }
Dans ce scénario, après avoir soumis votre formulaire avec un champ lastName vide, vous obtiendrez une page d'erreur puisque vous appliquez des règles de validation mais que vous ne le gérez pas du tout.
Exemple de ladite erreur: page d'exception
Contrôleur pour le scénario 2:
@RequestMapping("processForm") public String processFormData(@Valid @ModelAttribute("employee") Employee employee, BindingResult bindingResult){ return bindingResult.hasErrors() ? "employee-form" : "employee-confirmation-page"; }
Dans ce scénario, vous transmettez tous les résultats de cette validation à bindingResult, c'est donc à vous de décider quoi faire avec les résultats de validation de ce formulaire.
Contrôleur pour le scénario 3:
@RequestMapping("processForm") public String processFormData(@Valid @ModelAttribute("employee") Employee employee){ return "employee-confirmation-page"; } @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Map<String, String> invalidFormProcessor(MethodArgumentNotValidException ex){ //Your mapping of the errors...etc }
Dans ce scénario, vous ne gérez toujours pas les erreurs comme dans le premier scénario, mais vous le transmettez à une autre méthode qui prendra en charge l'exception que @Valid déclenche lors du traitement du modèle de formulaire. Vérifiez ceci pour voir quoi faire avec la cartographie et tout ça.
Pour résumer : @Valid seul avec ne rien faire de plus qui déclenche la validation des champs annotés JSR 303 de validation ( @NotNull, @Email, @Size, etc ... ), il vous reste à spécifier une stratégie de ce qu'il faut faire avec les résultats de ladite validation.
J'espère que j'ai pu dégager quelque chose pour les gens qui pourraient trébucher avec ça.
la source