Framework de validation de Spring 2.5+ avec annotations Java 5 [1ère partie : Durée 20min]

En quatre actes, nous allons illustrer la puissance du framework de validation de Spring sans écrire la moindre classe de validation.
En effet, quelques annotations dans vos beans (POJO), trois lignes de configuration et une ligne de code java; et le tour est joué! Le résultat obtenu est impressionnant!
Vos objets sont validés. De plus, la validation est faite côté serveur et client.
Nous détaillerons tout cela sur un exemple intéressant un peu plus loin.
Ma découverte du framework de validation de Spring me fait dire :
Avec Spring, la vie des développeurs (et des chefs de projet) devient un fleuve tranquille de bonnes pratiques même si l'apprentissage, lui, est loin de l'être!

Sans rentrer dans le débat sur la nécessité de valider les objets et du côté client et du côté serveur, ce framework concilie et satisfait les deux avis.

La démonstration qui va être donnée contient deux projets:
- Le premier, projet web Spring MVC avec maven, détaille comment valider, côté client et serveur, nos objets avec les meilleures pratiques.
- Le second, projet java standalone, illustre un certain nombre d'annotations du framework de validation avec peu de lignes de configuration xml.
Et, le tout avec très peu de code java et en recourant aux validateurs prédéfinis de ce framework.
Le résultat est déconcertant!
Ce framework nous épargne des dizaines de lignes de code java (sans parler du temps à consacrer à les tester/déboguer!).

La démo ci-après repose et applique les deux grands principes:

  • Tout est POJO,
  • Séparation des préoccupations.

Passons à la pratique.....
Un seul pré requis nécessaire : connaître le framework de Spring et Spring MVC.

 

Avertissement: Dépendances/classpath: le jar spring-modules-0.9.jar de Spring validation doit être dans le classpath car il n' est pas inclus dans les spring_xxxx.jar.
Pour un projet maven, ajouter dans le pom.xml la ligne:

 

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-modules</artifactId>
      <version>0.9</version>
    </dependency>

Le framework de validation de Spring se décline en quatre actes qui vont être détaillés par la suite:

ACTE 1:

  - Ecrire vos beans (POJO) entités.

Puis, pour leurs attributs à valider, ajouter les annotations appropriées tels @NotBlank, @Length, @Email, @Range, @InThePast, @InTheFuture,....


ACTE 2:

  - Déclarer un des validators prédéfinis de Spring
 dans son fichier de config comme suit:

 

<!-- Enable annotation-based validation
        using Bean Validation Framework -->
   <bean id="configurationLoader"  
    class=
     "o.springmodules.validation.bean.
       conf.loader.annotation.
      AnnotationBeanValidationConfigurationLoader"/>
   <bean id="validator" class=
      "o.springmodules.validation.bean
      .BeanValidator" 
      p:configurationLoader-ref="configurationLoader"/>

Notez que l'utilisation du namespace p: va rendre la configuration xml plus concise comme nous le verrons par la suite.

ACTE 3:

  
  - Dans le Controller du spring MVC, déclarer
le Validator annoté avec @Autowired comme suit:
//*** validator de spring validation	
  private Validator validator;
  @Autowired
  public setValidator(Validator validator){
    this.validator=validator;
  }

Pour le projet java Standalone, nous donnerons toutes les précisions utiles au moment de présenter l'exemple.

ACTE 4:

  - Ajouter dans cette même classe une seule ligne de code:
validator.validate(YOUR_BEAN_POJO, ..)

Et voilà !

Pour le peu d'effort déployé nous avons obtenu ceci :

index_errors
Et cela : capture2_index_errors

 

Ok, tout ça est bien! Mais comment cela fonctionne t-il ?

Avant de répondre, construisons ensemble un exemple de projet Spring MVC simple et détaillons chacun des 4 actes.

 

  Projet démo Web Spring MVC

Pour ce projet web exemple en Spring MVC nommé spring-mvc, nous aurons à manipuler :

  • Le(s) classe(s) POJOs : Personne.java et Client.java
  • Le fichier de configuration du contexte web de Spring : spring-mvc-servlet.xml
  • La classe du controller de Spring nommée ClientControllerSpringMVC.java
  • Le fichier « properties » nommé : messages.properties

ACTE1:

Ecrire les POJOs:

 

public class Personne implements Serializable {
	String nom;
	String prenom;
	// + setters/getters omis
}
public class Client extends Personne{
	long cliId;
	@NotBlank 
	@Length( max = 15) 
	private String cliNom;
        //***aucune regle de validation sur prenom
	private String cliPrenom;
	@NotBlank @Length(min=4) @Email
	private String cliEmail;
       //+setters / getters omis
	public String toString(){
		return "Id="+getCliId()+ " nom="+getNom()+
                      " prenom="+getPrenom();
	}
}

ACTE2:

Le fichier spring-mvc-servlet.xml contient ces lignes:

<?xml version="1.0" encoding="UTF-8"?>
<beans 
        xmlns=
"http://www.springframework.org/schema/beans" xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p=
"http://www.springframework.org/schema/p" xmlns:context=
"http://www.springframework.org/schema/context"
	xsi:schemaLocation=
 "http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/
  beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/
   context/spring-context-2.5.xsd"
 default-autowire="byName">
   <bean id="configurationLoader"  
    class=
     "o.springmodules.validation.bean.conf.
     loader.annotation.
    AnnotationBeanValidationConfigurationLoader"/> 
   <bean id="validator" class=
    "org.springmodules.validation.bean.BeanValidator" 
    p:configurationLoader-ref="configurationLoader"/> 
 
    <!-- Load messages --> 
   <bean id="messageSource"  
      class=
       "o.s.context.support.ResourceBundleMessageSource"
	   p:basenames="messages"/> 
   <bean class=
       "o.s.web.servlet.view.
        InternalResourceViewResolver"
	   p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>

Notez que certaines écritures des packages connus sont abrégées: par exemple, o.s pour désigner org.springframework.

ACTES 3 et 4Le controller et le fichier properties:

- La validation dans le controller:

Dans le controller, ajouter la déclaration du validator, par exemple, dans la méthode createClient comme suit :

//*** Controller de spring MVC avec les annotations	
@Controller("clientControllerSpring")
public class ClientControllerSpringMVC {
	final Logger logger=Logger.getLogger(getClass().getName());
 
 
==>	private Validator validator;  
	@Autowired         
	public void setValidator(Validator validator) {  
		this.validator = validator;  
	}  
 
	@RequestMapping(value = "/createClient.html", 
                                        method = RequestMethod.GET)  
	public ModelMap get() {     
		return new ModelMap("client", new Client());  
	}  
	@RequestMapping(value="/createClient.html",
                                       method = RequestMethod.POST)
	public String createClient(	@ModelAttribute("client") Client client,
                                      	BindingResult result,	ModelMap model) {
 
==>		validator.validate(client, result);
==>		if(result.hasErrors()){
			logger.warn("Erreurs sur le client "+result.toString());
			return null;
		}
			//Traitement métier;
 
		return Constants.SUCCESS;
	}
}

Les trois passages intéressants à observer sont précédés de la flèche "==>".

Enfin, compléter le fichier « messages.properties » sur l’exemple qui suit :

Client.cliNom[not.blank]=Merci de saisir votre nom.  
Client.cliNom[length]=Merci de saisir moins de {2} caracteres.

 

Pour finir, lancer la commande:

mvn jetty:run

Avec le navigateur saisir le lien:
http://localhost:8080/spring-mvc/createClient.html

Vous obtenez alors les formulaires des captures présentées précédemment.
Il ne vous reste qu'à tester les différentes possibilités de saisie dans les 2 champs "nom" et "email".

Conclusion :
Cette première partie a révélé la puissance de ce framework (add-on) de Spring intégré dans un projet Web MVC.
Seules les annotations @NotBlank, @Length et @Email ont été évoquées.

Nous poursuivons, dans la seconde partie de ce billet, la démonstration sur un projet Java standard.
D’autres annotations de validation vont être présentées : @InThePast, @Size, @Range,…

Nous montrons également comment créer notre propre classe de validation qui permet d’étendre les fonctionnalités de validation existantes.
D’un point de vue économique et de gestion de projet, l’effort et le temps gagnés avec ce framework sont manifestement énormes.

8 commentaires

  1. Dans le point 3 Développement je dirai également :

    * dans la mesure du possible, croiser certains développements et/ou tests afin de s’assurer que les bonnes pratiques sont effectivement utilisées et que l’implémentation des fonctionnalités de l’application soit compréhensible et maintenable par tous. Ne pas hésiter à remonter d’éventuels points trop complexes ou difficilement compréhensibles et proposer un refactoring.

    * lors de l’arrivé d’un nouveau développeur au sein de l’équipe, ne pas hésiter à faire, dans des proportions raisonnables, du pair programming afin qu’il puisse devenir opérationnel plus rapidemment.

  2. tres interessant mais j’aimerais savoir ou trouver le jar spring-modules-0.9.jar .
    je l’ai cherché partout.
    et aussi la deuxieme partie du tuto

    merci

  3. Merci beaucoup pour ce tuto qui est très intéressant, mais est-il possible de récupérer les sources du projet ?

  4. Bonjour,

    je tiens à faire une petite rectification. VOus dites au début que c’est une validation coté client et serveur, hors il faut savoir que la validation
    avec spring mvc n’existe pas encore et est toujours en cours de développement. Pour le verifier il suffit de mettre un point d’arret sur votre controleur. Si l’application s’arrete dessus c’est que vous etes deja coté serveur. Et dans votre exemple ca s’arretes à tous les coups. Votre tutoriel est malgré tout tres bien malgré cette petite erreur. Encore merci

    Bonne continuation.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.