Avec Spring MVC, il existe trois façons différentes d'effectuer une validation : en utilisant une annotation, manuellement, ou un mélange des deux. Il n'y a pas une seule et unique "façon propre et meilleure" de valider, mais il y en a probablement une qui correspond mieux à votre projet/problème/contexte.
Prenons un utilisateur :
public class User {
private String name;
...
}
Méthode 1 : Si vous avez Spring 3.x+ et une validation simple à effectuer, utilisez javax.validation.constraints
(également connues sous le nom d'annotations JSR-303).
public class User {
@NotNull
private String name;
...
}
Vous aurez besoin d'un fournisseur JSR-303 dans vos bibliothèques, comme par exemple Validateur Hibernate qui est l'implémentation de référence (cette bibliothèque n'a rien à voir avec les bases de données et le mapping relationnel, elle fait juste de la validation :-).
Dans votre contrôleur, vous auriez alors quelque chose comme :
@RequestMapping(value="/user", method=RequestMethod.POST)
public createUser(Model model, @Valid @ModelAttribute("user") User user, BindingResult result){
if (result.hasErrors()){
// do something
}
else {
// do something else
}
}
Remarquez le @Valid : si l'utilisateur a un nom nul, result.hasErrors() sera vrai.
Méthode 2 : Si vous disposez d'une validation complexe (comme une logique de validation d'entreprise importante, une validation conditionnelle sur plusieurs champs, etc.) ou si, pour une raison quelconque, vous ne pouvez pas utiliser la méthode 1, utilisez la validation manuelle. Une bonne pratique consiste à séparer le code du contrôleur de la logique de validation. Ne créez pas votre (vos) classe(s) de validation à partir de rien, Spring fournit un outil pratique de org.springframework.validation.Validator
(depuis Spring 2).
Disons que vous avez
public class User {
private String name;
private Integer birthYear;
private User responsibleUser;
...
}
et vous voulez faire une validation "complexe" du type : si l'âge de l'utilisateur est inférieur à 18 ans, responsibleUser ne doit pas être nul et l'âge de responsibleUser doit être supérieur à 21 ans.
Vous ferez quelque chose comme ceci
public class UserValidator implements Validator {
@Override
public boolean supports(Class clazz) {
return User.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
if(user.getName() == null) {
errors.rejectValue("name", "your_error_code");
}
// do "complex" validation here
}
}
Dans votre contrôleur, vous auriez alors :
@RequestMapping(value="/user", method=RequestMethod.POST)
public createUser(Model model, @ModelAttribute("user") User user, BindingResult result){
UserValidator userValidator = new UserValidator();
userValidator.validate(user, result);
if (result.hasErrors()){
// do something
}
else {
// do something else
}
}
S'il y a des erreurs de validation, result.hasErrors() sera vrai.
Note : Vous pouvez également définir le validateur dans une méthode @InitBinder du contrôleur, avec "binder.setValidator(...)". (dans ce cas, une utilisation mixte des méthodes 1 et 2 ne serait pas possible, car vous remplacez le validateur par défaut). Ou vous pourriez l'instancier dans le constructeur par défaut du contrôleur. Ou avoir un @Component/@Service UserValidator que vous injectez (@Autowired) dans votre contrôleur : très utile, car la plupart des validateurs sont des singletons + le mocking des tests unitaires devient plus facile + votre validateur peut appeler d'autres composants Spring.
Méthode 3 : Pourquoi ne pas utiliser une combinaison des deux méthodes ? Valider les choses simples, comme l'attribut "name", avec des annotations (c'est rapide à faire, concis et plus lisible). Garder les validations lourdes pour les validateurs (quand cela prendrait des heures de coder des annotations de validation complexes personnalisées, ou simplement quand il n'est pas possible d'utiliser les annotations). C'est ce que j'ai fait dans le cadre d'un projet précédent, et cela a fonctionné à merveille, rapidement et facilement.
Avertissement : vous ne devez pas vous tromper gestion des validations para traitement des exceptions . Lire cet article pour savoir quand les utiliser.
Références :
0 votes
spring.io/guides/gs/validating-form-input