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:
public class User {
private String name;
...
}
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).
public class User {
@NotNull
private String name;
...
}
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:
@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
}
}
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
public class User {
private String name;
private Integer birthYear;
private User responsibleUser;
...
}
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
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
}
}
Ensuite, dans votre contrôleur, vous auriez:
@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.
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 :