Je voudrais savoir quelle est la manière la plus propre et la meilleure pour effectuer la validation de formulaire des entrées utilisateur. J'ai vu certains développeurs implémenter org.springframework.validation.Validator
. Une question à ce sujet: je l'ai vu valider une classe. La classe doit-elle être remplie manuellement avec les valeurs de l'entrée utilisateur, puis transmise au validateur?
Je suis confus quant à la manière la plus propre et la meilleure de valider l'entrée de l'utilisateur. Je connais la méthode traditionnelle d'utilisation request.getParameter()
puis de vérification manuelle nulls
, mais je ne veux pas faire toute la validation dans mon Controller
. Quelques bons conseils dans ce domaine seront grandement appréciés. Je n'utilise pas Hibernate dans cette application.
la source
Réponses:
Avec Spring MVC, il existe 3 façons différentes d'effectuer la validation: en utilisant l'annotation, manuellement ou un mélange des deux. Il n'y a pas de «moyen le plus propre et le meilleur» de valider, mais il y en a probablement un qui correspond mieux à votre projet / problème / contexte.
Ayons un utilisateur:
Méthode 1: Si vous avez Spring 3.x + et une validation simple à faire, utilisez des
javax.validation.constraints
annotations (également appelées annotations JSR-303).Vous aurez besoin d'un fournisseur JSR-303 dans vos bibliothèques, comme Hibernate Validator qui est l'implémentation de référence (cette bibliothèque n'a rien à voir avec les bases de données et le mappage relationnel, elle ne fait que la validation :-).
Ensuite, dans votre contrôleur, vous auriez quelque chose comme:
Notez le @Valid: si l'utilisateur a un nom nul, result.hasErrors () sera vrai.
Méthode 2: Si vous avez une validation complexe (comme la logique de validation des grandes entreprises, la validation conditionnelle sur plusieurs champs, etc.), ou pour une raison quelconque, vous ne pouvez pas utiliser la méthode 1, utilisez la validation manuelle. Il est recommandé de séparer le code du contrôleur de la logique de validation. Ne créez pas vos classes de validation à partir de zéro, Spring fournit une
org.springframework.validation.Validator
interface pratique (depuis Spring 2).Alors disons que tu as
et vous voulez faire une validation "complexe" comme: si l'âge de l'utilisateur est inférieur à 18 ans, l'utilisateur responsable ne doit pas être nul et l'âge de l'utilisateur responsable doit être supérieur à 21 ans.
Tu feras quelque chose comme ça
Ensuite, dans votre contrôleur, vous auriez:
S'il y a des erreurs de validation, result.hasErrors () sera vrai.
Remarque: Vous pouvez également définir le validateur dans une méthode @InitBinder du contrôleur, avec "binder.setValidator (...)" (auquel cas une utilisation mixte des méthodes 1 et 2 ne serait pas possible, car vous remplacez la valeur par défaut validateur). Ou vous pouvez l'instancier dans le constructeur par défaut du contrôleur. Ou ayez un @ Component / @ Service UserValidator que vous injectez (@Autowired) dans votre contrôleur: très utile, car la plupart des validateurs sont des singletons + la simulation de test unitaire devient plus facile + votre validateur peut appeler d'autres composants Spring.
Méthode 3: Pourquoi ne pas utiliser une combinaison des deux méthodes? Validez les trucs simples, comme l'attribut "nom", avec des annotations (c'est rapide à faire, concis et plus lisible). Conservez les validations lourdes pour les validateurs (lorsqu'il faudrait des heures pour coder des annotations de validation complexes personnalisées, ou juste lorsqu'il n'est pas possible d'utiliser des annotations). Je l'ai fait sur un ancien projet, cela a fonctionné comme un charme, rapide et facile.
Attention: il ne faut pas confondre la gestion de la validation avec la gestion des exceptions . Lisez cet article pour savoir quand les utiliser.
Références :
la source
Il existe deux façons de valider les entrées utilisateur: les annotations et en héritant de la classe Validator de Spring. Pour les cas simples, les annotations sont agréables. Si vous avez besoin de validations complexes (comme la validation croisée, par exemple le champ "vérifier l'adresse e-mail"), ou si votre modèle est validé à plusieurs endroits dans votre application avec des règles différentes, ou si vous n'avez pas la possibilité de modifier votre objet de modèle en plaçant des annotations dessus, le validateur basé sur l'héritage de Spring est la voie à suivre. Je vais montrer des exemples des deux.
La partie de validation réelle est la même quel que soit le type de validation que vous utilisez:
Si vous utilisez des annotations, votre
Foo
classe pourrait ressembler à:Les annotations ci-dessus sont des
javax.validation.constraints
annotations. Vous pouvez également utiliser Hibernateorg.hibernate.validator.constraints
, mais il ne semble pas que vous utilisiez Hibernate.Alternativement, si vous implémentez Spring's Validator, vous créerez une classe comme suit:
Si vous utilisez le validateur ci-dessus, vous devez également lier le validateur au contrôleur Spring (pas nécessaire si vous utilisez des annotations):
Consultez également la documentation Spring .
J'espère que cela pourra aider.
la source
Foo
paramètre dans la méthode du gestionnaire. Pouvez-vous clarifier?Je voudrais prolonger la belle réponse de Jérôme Dalbert. J'ai trouvé très facile d'écrire vos propres validateurs d'annotations à la manière JSR-303. Vous n'êtes pas limité à avoir une validation "un champ". Vous pouvez créer votre propre annotation au niveau du type et avoir une validation complexe (voir les exemples ci-dessous). Je préfère cette méthode car je n'ai pas besoin de mélanger différents types de validation (Spring et JSR-303) comme le font Jérôme. De plus, ces validateurs sont "sensibles au printemps", vous pouvez donc utiliser @ Inject / @ Autowire hors de la boîte.
Exemple de validation d'objet personnalisé:
Exemple d'égalité des champs génériques:
la source
ElementType.METHOD
dans@Target
.Si vous avez la même logique de gestion des erreurs pour différents gestionnaires de méthodes, vous vous retrouverez avec de nombreux gestionnaires avec le modèle de code suivant:
Supposons que vous créez des services RESTful et que vous souhaitez renvoyer
400 Bad Request
des messages d'erreur pour chaque cas d'erreur de validation. Ensuite, la partie de gestion des erreurs serait la même pour chaque point de terminaison REST qui nécessite une validation. Répéter cette même logique dans chaque gestionnaire n'est pas si DRY ish!Une façon de résoudre ce problème consiste à supprimer immédiatement
BindingResult
après chaque bean à valider . Maintenant, votre gestionnaire serait comme ceci:De cette façon, si le bean lié n'était pas valide, un
MethodArgumentNotValidException
sera lancé par Spring. Vous pouvez définir unControllerAdvice
qui gère cette exception avec la même logique de gestion des erreurs:Vous pouvez toujours examiner le sous-jacent en
BindingResult
utilisant lagetBindingResult
méthode deMethodArgumentNotValidException
.la source
Trouver un exemple complet de validation Spring Mvc
la source
Mettez ce bean dans votre classe de configuration.
et ensuite vous pouvez utiliser
pour valider un bean manuellement. Ensuite, vous obtiendrez tous les résultats dans BindingResult et vous pourrez récupérer à partir de là.
la source