49
Spring par la pratique Arnaud Cogoluègnes Thierry Templier Julien Dubois Jean-Philippe Retaillé avec la contribution de Séverine Templier Roblou et de Olivier Salvatori 2 e édition Spring 2.5 et 3.0 © Groupe Eyrolles, 2006, 2009, ISBN : 978-2-212-12421-7

Splpv2 Chap 7

Embed Size (px)

DESCRIPTION

Splpv2 Chap 7

Citation preview

  • Springpar la pratique

    A r n a u d C o g o l u g n e s

    T h i e r r y T e m p l i e r

    J u l i e n D u b o i s

    J e a n - P h i l i p p e R e t a i l l

    a v e c l a c o n t r i b u t i o n d e S v e r i n e T e m p l i e r R o b l o u

    e t d e O l i v i e r S a l v a t o r i

    2e dition

    Spring 2.5

    et 3.0

    Titre_Spring2.0_XP 29/05/09 17:02 Page 2

    Groupe Eyrolles, 2006, 2009,

    ISBN : 978-2-212-12421-7

  • 7Spring MVC

    La mise en pratique du patron de conception MVC (Model View Controller) offre unemeilleure structuration du tiers de prsentation des applications Java EE en dissociant lesproccupations de dclenchement des traitements de la construction de la prsentation propre-ment dite. Les principaux frameworks MVC implmentent le type 2 de ce patron, qui instaureun point dentre unique ayant pour mission daiguiller les requtes vers la bonne entit detraitement.

    Le framework Spring offre une implmentation innovante du patron MVC par le biais dunframework nomm Spring MVC, qui profite des avantages de linjection de dpendances (voirchapitres 2 et 3) et qui, depuis la version 2.5, offre une intressante flexibilit grce aux anno-tations Java 5. Ce module permet ds lors de sabstraire de lAPI Servlet de Java EE, les infor-mations souhaites tant automatiquement mises disposition en tant que paramtres desmthodes des contrleurs.

    De plus, partir de la version 3.0, Spring MVC intgre un support permettant de grer la tech-nologie REST, les URL possdant la structure dcrite par cette dernire tant exploitable ennatif.

    Le prsent chapitre passe en revue les fonctionnalits et apports de ce module, qui met enuvre les principes gnraux du framework Spring, lesquels consistent masquer lAPIServlet et simplifier les dveloppements dapplications Java EE tout en favorisant leur struc-turation et leur flexibilit.

    Implmentation du pattern MVC de type 2 dans SpringCette section dcrit brivement limplmentation du patron de conception MVC de type 2dans le framework Spring.

    Spring Livre Page 183 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    184

    Nous prsenterons rapidement les concepts de base du type 2 de ce patron puis nous concen-trerons sur les principes de fonctionnement et constituants de Spring MVC, limplmentationdu patron MVC par Spring.

    Fonctionnement du patron MVC 2Le patron MVC est communment utilis dans les applications Java/Java EE pour raliser lacouche de prsentation des donnes aussi bien dans les applications Web que pour les clientslourds. Lorsquil est utilis dans le cadre de Java EE, il sappuie gnralement sur lAPIservlet ainsi que sur des technologies telles que JSP/JSTL.

    Il existe deux types de patrons MVC, celui dit de type 1, qui possde un contrleur par action,et celui dit de type 2, plus rcent et plus flexible, qui possde un contrleur unique. Nous nousconcentrerons sur ce dernier, puisquil est implment dans les frameworks MVC.

    La figure 7-1 illustre les diffrentes entits du type 2 du patron MVC ainsi que leurs interactionslors du traitement dune requte.

    Figure 7-1

    Entits mises en uvre dans le patron MVC de type 2

    ObjetObjet

    Objet

    Contrleur frontal Entit de traitement

    Fichier Classe

    Contient les donnes prsenter

    Aiguillage des requtes vers la bonne entit de

    traitement

    Ralise les traitements de la

    requte

    Construite la vue avec un pseudo

    template afin dafficher les

    donnes prsenter

    Construit la vue en Java afin dafficher

    les donnes prsenter

    Modle

    Contrleur

    Vue

    Spring Livre Page 184 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    185

    Les caractristiques des composants mis en uvre dans ce patron sont les suivantes :

    Modle. Permet de mettre disposition les informations utilises par la suite lors des trai-tements de prsentation. Cette entit est indpendante des API techniques et est constitueuniquement de Beans Java.

    Vue. Permet la prsentation des donnes du modle. Il existe plusieurs technologies deprsentation, parmi lesquelles JSP/JSTL, XML, les moteurs de templates Velocity et Free-Marker ou de simples classes Java pouvant gnrer diffrents types de formats.

    Contrleur. Gre les interactions avec le client tout en dclenchant les traitements appro-pris. Cette entit interagit directement avec les composants de la couche service mtier eta pour responsabilit la rcupration des donnes mises disposition dans le modle. Lorsde la mise en uvre du type 2 de ce patron, cette partie se compose dun point dentreunique pour toute lapplication et de plusieurs entits de traitement. Ce point dentreunique traite la requte et dirige les traitements vers lentit approprie. Pour cette raison,lentit de traitement est habituellement appele contrleur. Le contrleur frontal, ou contrleur faade , est intgr au framework MVC, et seuls les entits de traitement sontspcifiques lapplication.

    Un framework MVC implmente le contrleur faade, les mcanismes de gestion du modle,ainsi que ceux de slection et de construction de la vue. Lutilisateur dun tel framework a encharge le dveloppement et la configuration des entits de traitements et des vues choisies.

    Principes et composants de Spring MVCLe framework Spring fournit des intgrations avec les principaux frameworks MVC ainsi quesa propre implmentation. Forts de leur exprience dans le dveloppement dapplications JavaEE, ses concepteurs considrent que linjection de dpendances offre un apport de taille pourconcevoir et structurer des applications fondes sur le patron MVC.

    Prcisons que Spring MVC ne constitue quune partie du support relatif aux applications Web.Le framework Spring offre dautres fonctionnalits permettant notamment le chargement descontextes applicatifs de manire transparente ainsi que des intgrations avec dautresframeworks MVC, tels JSF, WebWork ou Tapestry.

    Parmi les principes fondateurs de Spring MVC, remarquons notamment les suivants :

    Utilisation du conteneur lger afin de configurer les diffrentes entits du patron MVC et debnficier de toutes les fonctionnalits du framework Spring, notamment au niveau de larsolution des dpendances.

    Favorisation de la flexibilit et du dcouplage des diffrentes entits mises en uvre grce la programmation par interface.

    Utilisation dune hirarchie de contextes applicatifs afin de raliser une sparation logiquedes diffrents composants de lapplication. Par exemple, les composants des servicesmtier et des couches infrieures nont pas accs ceux du MVC.

    Spring Livre Page 185 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    186

    Les composants du MVC ont pour leur part les principales caractristiques suivantes :

    partir de la version 2.5 de Spring, la gestion de laiguillage et la configuration des contr-leurs MVC se ralisent par lintermdiaire dannotations. Par ce biais, Spring MVC permetde masquer lutilisation de lAPI servlet et favorise la mise en uvre des tests unitaires ceniveau. Lapproche fonde sur les classes dimplmentation de contrleurs est dsormaisdprcie.

    Gestion des formulaires en se fondant sur les annotations relatives aux contrleurs afin nonseulement de charger et dafficher les donnes du formulaire, mais galement de grer leursoumission. Ces donnes sont utilises pour remplir directement un Bean sans lien avecSpring MVC, qui peut tre valid si ncessaire. Des mcanismes de mappage et de conversiondes donnes sont intgrs et extensibles selon les besoins.

    Abstraction de limplmentation des vues par rapport aux contrleurs permettant dechanger de technologie de prsentation sans impacter le contrleur.

    Pour mettre en uvre ces principes et composants, Spring MVC sappuie sur les entits illus-tres la figure 7-2. Le traitement dune requte passe successivement par les diffrentes entitsen commenant par la servlet DispatcherServlet et en finissant par la vue choisie.

    Les principaux composants de Spring MVC peuvent tre rpartis en trois groupes, selon leurfonction :

    Gestion du contrleur faade et des contextes applicatifs. Permet de spcifier les fichiers desdiffrents contextes ainsi que leurs chargements. Le contrleur faade doit tre configur defaon spcifier laccs lapplication.

    Figure 7-2

    Entits de traitement des requtes de Spring MVC

    Contexte de Spring MVC

    Contexte de l'application Web

    Contexte partag (facultatif)

    DispatcherServlet HandlerMapping Controller ViewResolver View

    Contrleur faadeAiguillage des

    requtes vers le bon contrleur

    Entits ralisant les traitements de la

    requte

    Mcanisme de slection de la vue

    souhaite

    Entit construisant la vue

    ModelAndView

    Spring Livre Page 186 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    187

    Gestion des contrleurs. Consiste configurer la stratgie daccs aux contrleurs, ainsique leurs diffrentes classes dimplmentation et leurs proprits. Laiguillage se configuredsormais directement dans les classes mettant en uvre des contrleurs en se fondant surdes annotations. Ces dernires permettent galement de mettre facilement disposition lesdonnes prsentes dans la requte, la session et le modle.

    Gestion des vues. Consiste configurer la ou les stratgies de rsolution des vues ainsi queles frameworks ou technologies de vue mis en uvre.

    Initialisation du framework Spring MVCLinitialisation du framework Spring MVC seffectue en deux parties, essentiellement au seindu fichier web.xml puisquelle utilise des mcanismes de la spcification Java EE servlet.

    Gestion des contextesLe framework Spring permet de charger automatiquement les contextes applicatifs en utilisantles mcanismes des conteneurs de servlets.

    Dans le cadre dapplications Java EE, une hirarchie de contextes est mise en uvre afin deregrouper et disoler de manire logique les diffrents composants. De la sorte, un composantdune couche ne peut accder celui dune couche suprieure.

    Le framework Spring offre une hirarchie pour les trois contextes suivants :

    Contexte racine. Ce contexte est trs utile pour partager des objets dune mme biblio-thque entre plusieurs modules dune mme application Java EE pour un mme chargeur declasses.

    Contexte de lapplication Web. Stock dans le ServletContext, ce contexte doit contenir lalogique mtier ainsi que celle de laccs aux donnes.

    Contexte du framework MVC. Gr par le contrleur faade du framework, ce contexte doitcontenir tous les composants relatifs au framework MVC utilis.

    Contexte applicatif Spring

    Rappelons quun contexte applicatif correspond au conteneur lger en lui-mme, dont la fonction est degrer des Beans. Le framework offre galement un mcanisme permettant de dfinir une hirarchie decontextes afin de raliser une sparation logique entre des groupes de Beans. Dans le cas du MVC, ilsagit dempcher lutilisation de composants du MVC par des composants service mtier ou daccsaux donnes.

    Spring Livre Page 187 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    188

    La figure 7-3 illustre cette hirarchie ainsi que la porte des diffrents contextes.

    La mise en uvre du contexte de lapplication Web est obligatoire, tandis que celle ducontexte racine est optionnelle et nest donc pas dtaille ici. Si ce dernier est omis,Spring positionne de manire transparente celui de lapplication Web en tant que contexteracine.

    Linitialisation du contexte de lapplication Web, que nous dtaillons dans ce chapitre, estindpendante du framework MVC choisi et utilise les mcanismes du conteneur de servlets.Sa configuration est identique dans le cadre du support dautres frameworks MVC.

    Chargement du contexte de lapplication Web

    Le framework Spring fournit une implmentation de la classe ServletContextListener de laspcification servlet permettant de configurer et dinitialiser ce contexte au dmarrage et de lefinaliser larrt de lapplication Web.

    Cette fonctionnalit est utilisable avec un conteneur de servlets supportant au moins laversion 2.3 de la spcification. Cet observateur paramtre les fichiers de configuration XMLdu contexte en ajoutant les lignes suivantes dans le fichier web.xml de lapplication :

    contextConfigLocation

    /WEB-INF/applicationContext*.xml

    org.springframework.web.context.ContextLoaderListener

    Figure 7-3

    Hirarchie des contextes de Spring pour une application Web

    Contexte racine

    Contexte WebApp Contexte WebApp

    Contexte MVC Contexte MVC

    Singleton

    ServletContext

    Servlet

    Spring Livre Page 188 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    189

    Chargement du contexte de Spring MVC

    La configuration tout comme le chargement de ce contexte sont lis ceux de la servlet ducontrleur faade de Spring MVC. Prcisons que, par dfaut, cette dernire initialise uncontexte applicatif fond sur un fichier -servlet.xml, lequel utilise le nom de laservlet prcdente pour . Ce fichier se situe par dfaut dans le rpertoire WEB-INF ; la valeur de est spcifie grce la balise servlet-name.

    Dans notre tude de cas, la servlet de Spring MVC sappelle tudu. Le fichier tudu-servlet.xmlcontient les diffrents composants utiliss par ce framework, comme les contrleurs, les vueset les entits de rsolution des requtes et des vues.

    Nous pouvons personnaliser le nom de ce fichier laide du paramtre dinitialisationcontextConfigLocation de la servlet. Le code suivant montre comment spcifier un fichiermvc-context.xml pour le contexte de Spring MVC par lintermdiaire du paramtre prc-demment cit () :

    (...) tudu (...) contextConfigLocation /WEB-INF/mvc-context.xml

    Initialisation du contrleur faade

    Le fait que le framework Spring MVC implmente le patron MVC de type 2 entrane quilmet en uvre un contrleur faade pour diriger les traitements vers des classes dsignes parle terme Controller dans Spring MVC.

    Ce contrleur faade est implment par le biais de la servlet DispatcherServlet du packageorg.springframework.web.servlet, cette dernire devant tre configure dans le fichier WEB-INF/web.xml.

    Le mappage de la ressource () est dfini au niveau du conteneur de servlets dans le fichierweb.xml localis dans le rpertoire WEB-INF. Spring ne pose aucune restriction ce niveau,comme lillustre le code suivant :

    Le contrleur faade

    Cette entit correspond lunique point daccs de lapplication Web. Son rle est de rediriger les traite-ments vers le bon contrleur en se fondant sur ladresse daccs pour traiter la requte. Dans le casdapplications Web, ce contrleur est implment par le biais dune servlet, qui est gnralement fourniepar le framework MVC utilis.

    Spring Livre Page 189 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    190

    ... tudu org.springframework.web.servlet.DispatcherServlet 1 tudu *.do

    Support des annotations pour les contrleurs

    Comme indiqu prcdemment, partir de la version 2.5 de Spring, la configuration descontrleurs se ralise par lintermdiaire dannotations. Bien que cette approche soit celle utiliser, il reste nanmoins ncessaire de lactiver dans la configuration de Spring.

    Cet aspect peut tre mis en uvre de deux manires linstar de la configuration des compo-sants par lintermdiaire des annotations dans Spring.

    La premire approche consiste spcifier une implmentation de linterfaceHandlerMapping fonde sur les annotations. Spring MVC propose la classe Default-AnnotationHandlerMapping cet effet. Cette dernire peut tre utilise conjointement avec laclasse AnnotationMethodHandlerAdapter afin de configurer les mthodes de traitements desrequtes dans les contrleurs avec des annotations.

    Avec cette approche, les Beans des contrleurs doivent tre configurs en tant que Beans dansle contexte de Spring MVC.

    Le code suivant dcrit lutilisation de ces deux classes dans le fichier de configuration Springassoci la servlet DispatcherServlet de Spring MVC :

    La seconde consiste en lutilisation de la balise component-scan de lespace de nommagecontext afin de dtecter tous les composants prsents et notamment les contrleurs SpringMVC. Ces derniers nont plus tre dfinis en tant que Beans dans la configuration de Spring.Dans ce contexte, lannotation Autowired doit tre utilise pour linjection de dpendances.Pour plus de prcision, reportez-vous au chapitre 2.

    Spring Livre Page 190 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    191

    La configuration de cet aspect se ralise dans le fichier de configuration Spring associ laservlet DispatcherServlet de Spring MVC :

    Il est recommand de nutiliser la premire approche que si une personnalisation de la strat-gie de mappage des requtes est envisage. La seconde approche reste donc celle utiliser pardfaut.

    En rsum

    Cette section a dtaill les mcanismes gnraux de fonctionnement du patron MVC de type 2ainsi que la structuration utilise dans le framework Spring MVC afin de le mettre en uvre.Nous avons pu constater que les entits utilises permettent de bien modulariser les traitements etdisoler le contrleur de la vue.

    Les mcanismes de chargement des contextes, de configuration du contrleur faade et delapproche dirige par les annotations du framework Spring MVC ont galement t dcrits.

    Nous allons maintenant dtailler la faon dont Spring MVC gre les requtes et les vues.

    Traitement des requtesComme nous lavons voqu prcdemment, lapproche de Spring MVC afin de traiter lesrequtes est dsormais compltement dirige par des annotations. Ces dernires permettent deconfigurer aussi bien laiguillage des requtes que les contrleurs eux-mmes.

    Il est noter dans ce contexte que lannotation Controller permet de prciser quune classecorrespond un contrleur MVC et quelle contient les traitements correspondants.

    Une fois cette annotation positionne, le mappage des URI doit tre dfini afin de slectionnerle contrleur de traitement pour une requte Web donne. Cela se configure galement par lebiais des annotations, ainsi que nous le dtaillons dans la prochaine section.

    Slection du contrleur

    Comme pour tout framework implmentant le patron MVC de type 2, un mcanisme decorrespondance entre la classe de traitement approprie et lURI de la requte est intgr. Leframework configure cette correspondance en se fondant sur les informations prsentes dansles annotations RequestMapping des contrleurs.

    Afin de configurer ce mcanisme, il est indispensable de bien comprendre la structure delURL dune requte, qui apparat toujours sous la forme suivante dans les applications JavaEE :

    http://://

    Spring Livre Page 191 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    192

    LURI correspond la fin de lURL :

    //

    Lalias de lapplication Web, , est configur au niveau du serveur dapplica-tions, contrairement celui de la ressource Web, , qui se ralise au seinde lapplication.

    Dans un premier temps, laccs la servlet DispatcherServlet de Spring MVC est paramtrdans le fichier web.xml du rpertoire WEB-INF afin de prendre en compte un ensembledURI avec des mappages de la forme *, /quelquechose/* ou *.quelquechose. Nous avonsdtaill la configuration de cet aspect la section Initialisation du contrleur faade prc-demment dans ce chapitre.

    Avec les annotations, limplmentation DefaultAnnotationHandlerMapping de linterfaceHandlerMapping est utilise implicitement ou explicitement suivant la configuration. Elle sefonde sur les informations prsentes dans les annotations de type RequestMapping. Cettedernire peut tre prsente aussi bien au niveau de la classe du contrleur que des mthodes dece dernier. Les informations spcifies par ce biais au niveau de la classe lui sont globales,avec la possibilit de les surcharger au niveau des mthodes.

    Cet aspect offre dintressantes perspectives afin de configurer diffrents types de contrleurs,tels que ceux entres multiples ou ddis la gestion des formulaires. Nous dtaillons cetaspect plus loin dans ce chapitre.

    Le tableau 7-1 rcapitule les diffrentes proprits utilisables de lannotation RequestMapping.

    Lexemple suivant illustre lutilisation de lannotation au niveau de la classe du contr-leur () afin de spcifier la valeur du mappage ainsi quau niveau de la mthode ddieau traitement de la requte () :

    @Controller@RequestMapping("/welcome.do")public class WelcomeController {

    @RequestMapping public void welcome() { (...) }}

    Tableau 7-1. Proprits de lannotation RequestMapping

    Proprit Type Description

    method String[] Spcifie la ou les mthodes HTTP suppor tes par le mappage. La spcification dunemthode se ralise par lintermdiaire des valeurs de lnumration RequestMethod.

    params String[] Permet de raliser un mappage plus fin en se fondant sur les paramtres de la requte.La prsence ou la non-prsence (avec loprateur !) dun paramtre peut tre utilise.

    value String[] Correspond la valeur de lannotation. Cette proprit permet de dfinir la ou les valeursdfinissant le mappage de llment. Ces valeurs peuvent ventuellement correspondre des expressions rgulires au format Ant.

    Spring Livre Page 192 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    193

    Dans lexemple ci-dessus, lannotation au niveau de la mthode reprend les valeurs desproprits de lannotation positionne au niveau de la classe.

    Il est galement possible de ne spcifier le mappage quau niveau de la mthode de traite-ment () :

    @Controller

    public class WelcomeController {

    @RequestMapping("/welcome.do") public void welcome() {

    (...)

    }

    }

    Pour finir, il est galement possible de spcifier plusieurs mappages () pour une mmeannotation avec la mthode HTTP daccs souhaite () ainsi quun filtrage se fondant surles valeurs des paramtres de la requte (), comme lillustre le code suivant :

    @Controller

    public class WelcomeController {

    @RequestMapping(

    value={"/welcome.do", "/index.do"), method=RequestMethod.GET params={"auth=true", "refresh", "!authenticate"} public void welcome() {

    (...)

    }

    }

    Dans lexemple ci-dessus, la mthode welcome du contrleur est appele pour les URI //welcome.do ou //index.do seulement par la mthode HTTPGET si les conditions sur les paramtres sont vrifis. Dans notre cas, le paramtre auth doitpossder la valeur true, le paramtre refresh doit tre prsent, et le paramtre authenticatene doit pas ltre.

    Les types de contrleurs

    Comme indiqu prcdemment, Spring MVC fournit lannotation Controller afin de dfinirune classe en tant que contrleur. Cette approche est particulirement flexible mettre enuvre, car elle permet de sabstraire de lAPI Servlet et de dfinir le contenu des contrleurset les signatures des mthodes en fonction des besoins.

    Les sections qui suivent dtaillent les diffrents mcanismes et dclinaisons utilisables afin demettre en uvre des contrleurs dans Spring MVC.

    Spring Livre Page 193 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    194

    Contrleurs de base

    Pour mettre en uvre les contrleurs de ce type, lutilisation de lannotation RequestMappingprcdemment dcrite est suffisante. Les mthodes sur lesquelles est applique cette annota-tion prennent en paramtres des objets de type HttpServletRequest et HttpServletResponse etretournent un objet de type ModelAndView.

    Ces contrleurs peuvent tre entres multiples puisquil est possible en standard de positionnerune annotation RequestMapping sur plusieurs de leurs mthodes.

    Le code suivant illustre la mise en uvre dun contrleur simple en se fondant sur lannotationRequestMapping () :

    @Controllerpublic class ShowTodosController { (...) @RequestMapping("/showTodos.do") public ModelAndView showTodos(HttpServletRequest request, HttpServletResponse response) throws Exception {

    Collection todoLists = new TreeSet( userManager.getCurrentUser().getTodoLists());

    String listId = null; if (!todoLists.isEmpty()) { listId = request.getParameter("listId"); if (listId != null) { listId = todoLists.iterator().next().getListId()); } }

    Map model = new HashMap(); model.put("defaultList", listId); return new ModelAndView("todos", model); }}

    Aucune autre configuration, si ce nest linjection des dpendances avec lannotationAutowired, nest ncessaire.

    Spring MVC offre nanmoins une approche intressante et flexible afin de supporter diffren-tes signatures de mthodes de traitements des contrleurs et de spcifier des mthodes deremplissage du modle. Nous dcrivons cette approche, dont lutilisation est recommande,aux sections suivantes.

    Point dentre

    Dans le contexte du pattern MVC, un point dentre correspond une mthode dun composant qui peuttre utilise par le conteneur ou le framework qui le gre afin de traiter une requte. La signature de cettemthode suit habituellement des conventions spcifiques afin de pouvoir tre appele.

    Spring Livre Page 194 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    195

    Support des paramtres et retours des mthodes

    En parallle de la signature type pour les mthodes de traitement des contrleurs, signaturehrite des prcdentes versions de Spring MVC, le framework permet si ncessaire desabstraire des API Servlet et de Spring MVC. Il est en ce cas possible de spcifier une signa-ture de mthodes en fonction de ses besoins. La dtermination des points dentre duncontrleur est dtermine par la prsence de lannotation RequestMapping.

    Il est noter que cette approche est galement valable pour les mthodes annotes parModelAttribute et InitBinder.

    Spring MVC permet de passer directement des paramtres prcis soit par type, soit en sefondant sur des annotations supplmentaires. Le framework permet en outre de retournerdiffrents types en fonction de ses besoins. Ces deux possibilits peuvent se combiner pourune plus grande flexibilit.

    Le tableau 7-2 rcapitule les diffrents paramtres supports par Spring MVC pour les mthodesde gestion des requtes Web, et le tableau 7-3 les types de retours possibles.

    Tableau 7-2. Types de paramtres possibles pour une mthode dun contrleur

    Type de paramtre Description

    ServletRequest ou HttpServletRequest Requte par lintermdiaire de lAPI Servlet.

    ServletResponse ou HttpServletResponse Rponse de la requte par lintermdiaire de lAPI Servlet.

    HttpSession Session de linitiateur de la requte par lintermdiaire de lAPIServlet.

    WebRequest ou NativeWebRequest Accs dune manire gnrique aux paramtres de la requtesans utiliser lAPI Servlet.

    Locale Couple pays et langue associ la requte.

    InputStream ou Reader Flux dentre associ la requte afin davoir accs au contenude la requte.

    OutputStream ou Writer Flux de sortie associ la rponse de la requte afin de gnrerle contenu de la rponse.

    Paramtre annot par RequestParam Paramtre de la requte dont lidentifiant est celui spcifi danslannotation. Spring a la responsabilit de le rcuprer dans larequte et de le convertir dans le type attendu.

    Map, Model ou ModelMap Modle utilis pour les donnes prsentes dans la vue. Celui-ci offre la possibilit davoir accs aux donnes contenues dansle modle et de les manipuler.

    Type correspondant un objet de formulaire et annot par ModelAttribute

    Objet de formulaire rcupr dans le modle en se fondant surlidentifiant spcifi dans lannotation.

    Errors ou BindingResult Rsultat du mappage et validation dobjets de formulaire. Unevalidation personnalise peut se fonder sur ce paramtre afindenregistrer les erreurs.

    SessionStatus Dans le cas dun formulaire mis en uvre sur plusieurs pages,cet objet offre la possibilit de relcher les ressources mises enuvre cet effet.

    Spring Livre Page 195 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    196

    Comme le montrent ces tableaux, deux annotations sont proposes pour le traitement desrequtes, RequestParam et ModelMap. Nous dcrivons dans cette section lutilisation de lapremire et dtaillerons la seconde la section Contrleur de gestion de formulaire .

    Lannotation RequestParam offre la possibilit de rfrencer un paramtre de la requte par sonnom. Lobjet correspondant est alors pass en tant que paramtre. ce niveau, une conversionde type est ralise si ncessaire afin de coller avec le type attendu pour le paramtre.

    Le code suivant illustre lutilisation de lannotation RequestParam afin davoir accs au para-mtre de la requte didentifiant listId par lintermdiaire dun paramtre dune mthode detraitement du contrleur :

    @Controllerpublic class ShowTodosController { (...) @RequestMapping("/showTodos.do") public ModelAndView showTodos( @RequestParam String listId) throws Exception {

    Collection todoLists = new TreeSet( userManager.getCurrentUser().getTodoLists());

    if (!todoLists.isEmpty()) { if (listId != null) { listId = todoLists.iterator().next().getListId(); } }

    Tableau 7-3. Types de retours possibles pour une mthode dun contrleur

    Type de retour Description

    Map Objet contenant les donnes du modle utiliser dans la vue. Lidentifiant de la vue estimplicitement dduit par Spring MVC (voir le cas void, o aucun objet nest retourn).

    Model Identique au prcdent.

    ModelAndView Objet regroupant lidentifiant de la vue utiliser suite aux traitements du contrleur et lecontenu du modle pour cette dernire.

    String Identifiant de la vue utiliser suite aux traitements du contrleur.

    View Vue utiliser suite aux traitements du contrleur.

    void Dans le cas o aucun objet nest retourn, Spring MVC dduit implicitement lidentifiantde la vue utiliser. Ce mcanisme se fonde sur une implmentation de linterfaceRequestToViewNameTranslator. Limplmentation par dfaut extrait cet identifiant enenlevant les prfixe et suffixe de lURI. Par exemple, pour un URI /showTodos.do,lidentifiant de la vue est showTodos.

    Nimporte quel type annot par ModelAttri-bute

    Objet ajouter aux donnes du modle aprs lexcution de la mthode et avant cellede la vue. Lidentifiant utilis dans lajout correspond celui de lannotation.

    Spring Livre Page 196 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    197

    Map model = new HashMap(); model.put("defaultList", listId); return new ModelAndView("todos", model); }}

    Lors de lomission de la valeur de lannotation RequestParam, le nom du paramtre sur lequelelle porte est utilis. Ainsi, lutilisation de lannotation dans lexemple prcdent est similaire la suivante () :

    @Controllerpublic class ShowTodosController { (...) @RequestMapping("/showTodos.do") public ModelAndView showTodos( @RequestParam("listId") String listId) throws Exception { (...) }}

    Par dfaut, lutilisation de lannotation RequestParam ncessite la prsence du paramtre dansla requte. Lattribut required de lannotation permet de paramtrer ce comportement afin derendre le paramtre optionnel, comme le montre le code suivant () :

    @RequestMapping("/showTodos.do") public ModelAndView showTodos( @RequestParam(value="listId", required="false") String listId) throws Exception { (...)}

    Les mthodes de traitement des contrleurs acceptent galement un paramtre de typeModelMap, ce paramtre correspondant aux donnes du modle. En utilisant ce paramtre, il estpossible de manipuler les donnes du modle et den ajouter de nouvelles. Dans ce cas, il nestplus ncessaire de retourner un objet de type ModelAndView ; une chane de caractres corres-pondant lidentifiant de la vue suffit.

    Le code suivant illustre ladaptation de lexemple prcdent () afin dutiliser cemcanisme :

    @Controllerpublic class ShowTodosController { (...) @RequestMapping("/showTodos.do") public String showTodos( @RequestParam String listId, ModelMap model) throws Exception {

    Collection todoLists = new TreeSet( userManager.getCurrentUser().getTodoLists());

    Spring Livre Page 197 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    198

    if (!todoLists.isEmpty()) {

    if (listId != null) {

    listId = todoLists.iterator().next().getListId();

    }

    }

    model.addAttribute("defaultList", listId); return "todos"; }

    }

    Les principaux autres types de paramtres et de retour sont dcrits dans les sections suivantes.

    Contrleur de gestion de formulaire

    Spring MVC fournit un support pour laffichage des donnes des formulaires et leur soumis-sion laide dannotations. Ce support se fonde sur les diffrents concepts et annotationsdcrits aux sections prcdentes.

    Bien que ce type de contrleur utilise un Bean afin de stocker les informations des formulai-res, aucune configuration nest raliser pour linjection de dpendances. Il suffit que ce Beansoit prsent dans les donnes du modle et que lidentifiant correspondant soit spcifi dans leformulaire.

    La section suivante se penche sur la faon dimplmenter la gestion des formulaires HTML aumoyen de lapproche oriente annotations de Spring MVC.

    Affichage du formulaire

    Lutilisation des annotations RequestMapping, ModelAttribute et InitBinding permet de char-ger les diffrentes entits ncessaires laffichage du formulaire dans la vue. Les mthodessur lesquelles sont appliques ces annotations, prennent alors part au cycle de traitement de larequte et adressent des problmatiques distinctes et senchanent dans un ordre bien prcis.

    Laffichage du formulaire est ralis grce lappel dune mthode de traitement de la requtepar le biais de la mthode GET. Le cycle denchanement des mthodes est illustr lafigure 7-4.

    Spring MVC permet dinitialiser lobjet de formulaire en se fondant sur une mthode annotepar ModelAttribute. Cet objet doit tre retourn par la mthode et est automatiquement ajoutdans le modle. Il peut donc tre utilis par la suite dans la vue pour initialiser le formulairecorrespondant.

    Le comportement habituel consiste crer une instance vierge chaque demande daffichagedu formulaire si aucun paramtre nest spcifi. Si un paramtre est prsent dans la requte,celui-ci peut tre alors utilis, par exemple, afin de rcuprer une instance initialise avec desvaleurs de la base de donnes.

    Spring Livre Page 198 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    199

    Le code suivant, tir de Tudu Lists, donne un exemple dutilisation de la mthodeinitFormObject () de ce type :

    (...)public class MyInfoController { (...) @ModelAttribute("userinfo") public UserInfoData initFormObject( HttpServletRequest request) { String login = request.getRemoteUser(); User user = userManager.findUser(login); UserInfoData data = new UserInfoData(); data.setPassword(user.getPassword()); data.setVerifyPassword(user.getPassword()); data.setFirstName(user.getFirstName()); data.setLastName(user.getLastName()); data.setEmail(user.getEmail()); return data; } (...)}

    Les PropertyEditor personnaliss sont ajouts par lintermdiaire dune mthode annote parInitBinder afin de convertir les proprits du Bean de formulaire en chanes de caractres affi-chables dans des champs. Cette mthode doit possder un paramtre de type WebDataBinderafin de pouvoir les enregistrer.

    Figure 7-4

    Enchanement des mthodes permettant laffichage des donnes dun formulaire

    Mthodes annotes par ModelAttribute

    Requte GET

    Mthode annote par InitBinder

    Mthode annote par RequestMapping avec

    method=RequestMethod.GET

    Vue

    Mthode annote par InitBinder

    Spring Livre Page 199 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    200

    Le code suivant indique la faon dajouter un PropertyEditor dans un contrleur de gestion deformulaire en se fondant sur lannotation InitBinder () :

    (...)public class MyInfoController { (...) @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(MyClass.class, new MyPropertyEditor()); } (...)}

    Cette mthode est utilise afin dafficher les valeurs du Bean de formulaire dans la vue corres-pondante sous forme de chanes de caractres.

    Il est possible dajouter des lments dans le modle par lintermdiaire de lannotationModelAttribute. Ces lments peuvent tre utiliss dans la construction du formulaire afinnotamment dinitialiser des listes de slection, des boutons radio ou des cases cocher. Autantde mthodes que dlments ajouter doivent tre dfinies.

    Le code suivant montre la faon dajouter les donnes ncessaires afin dinitialiser un formu-laire en se fondant sur lannotation ModelAttribute () :

    (...)public class MyInfoController { (...) @ModelAttribute("datas") public List populateDataList() { List datas = new ArrayList(); datas.add("my data"); return datas; } (...)}

    Pour finir, il convient de dfinir une mthode de traitement ddie laffichage du formulaire.Cette dernire doit tre annote avec RequestMapping et possder la proprit method avec lavaleur RequestMethod.GET. Le mappage avec lURI peut tre spcifi ce niveau ou globale-ment au niveau de la classe. Cette mthode ne possde pas particulirement de traitements,mais spcifie la vue correspondant au formulaire.

    Le code suivant illustre un exemple de mthode de ce type annot par RequestMapping () :

    (...)public class MyInfoController { (...) @RequestMapping(method = RequestMethod.GET) public String showForm() { return "userinfo"; } (...)}

    Spring Livre Page 200 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    201

    Soumission du formulaire

    Lutilisation des annotations RequestMapping, ModelAttribute et InitBinding permet de dfinirdes mthodes de remplissage de lobjet de formulaire avec les donnes soumises et de les trai-ter. Ces mthodes adressent des problmatiques distinctes et senchanent dans un ordreprcis.

    La soumission du formulaire est traite grce lappel dune mthode de traitement de larequte par la mthode POST. Le cycle denchanement des mthodes est illustr la figure 7-5.

    Les premires mthodes annotes avec RequestMapping et InitBinder (respectivementinitFormObject, initBinder) fonctionnent de la mme manire que prcdemment

    Une validation des donnes dun formulaire peut tre mise en uvre si ncessaire. La valida-tion lie au mappage des donnes du formulaire dans lobjet correspondant est directementintgre dans le cycle de traitements. Par contre, avec lapproche fonde sur les annotations,Spring MVC nintgre pas les validations personnalises dans ce cycle. Nanmoins, il estrecommand dutiliser linterface Validator afin de regrouper ces traitements. Le code decette interface est le suivant :

    public interface Validator { boolean supports(Class clazz); void validate(Object obj, Errors errors);}

    La mthode supports permet de spcifier sur quel Bean de formulaire peut tre appliquelentit de validation. La mthode validate doit contenir limplmentation de la validation etutiliser linstance de linterface Errors associe.

    Figure 7-5

    Enchanement des mthodes permettant la soumission des donnes dun formulaire

    Mthodes annotes par ModelAttribute

    Mthode annote par InitBinder

    Mthode annote par RequestMapping avec

    method=RequestMethod.POST

    Vue

    Mthode annote par InitBinder

    Requte POST

    Spring Livre Page 201 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    202

    Le ou les validateurs sont associs au contrleur soit par injection de dpendances, soit parune instanciation directe, cette dernire tant peu coteuse.Le code suivant de la classe RegisterValidator montre que limplmentation du validateurpermet de spcifier des erreurs aussi bien un niveau global () que sur chaque proprit duformulaire () en sappuyant sur linterface Errors :

    public class RegisterValidator implements Validator {

    public boolean supports(Class clazz) { return RegisterData.class.isAssignableFrom(clazz); }

    public void validate(Object command, Errors errors) { ValidationUtils.rejectIfEmptyOrWhitespace(errors, "login", "errors.required", new Object[] {"login"}, ""); ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "errors.required", new Object[] {"password"}, "");

    ValidationUtils.rejectIfEmptyOrWhitespace( errors, "verifyPassword", "errors.required", new Object[] {"verifyPassword"}, ""); if( !data.getPassword().equals(data.getVerifyPassword()) ) { errors.rejectValue("verifyPassword", "errors.required", new Object[] {"verifyPassword"}, ""); }

    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "errors.required", new Object[] {"firstName"}, ""); ValidationUtils.rejectIfEmptyOrWhitespace( errors, "lastName", "errors.required", new Object[] {"lastName"}, "");

    if( errors.hasErrors() ) { errors.reject("register.info.1"); } }}

    La mthode de traitement ddie la soumission du formulaire doit tre annote avecRequestMapping et possder la proprit method avec la valeur RequestMethod.POST. Cettedernire prend en paramtre lobjet de formulaire, objet annot par ModelAttribute et a laresponsabilit de traiter cet objet.

    Le code suivant illustre la mise en uvre dune mthode de ce type dans le cadre du contrleurMyInfoController, mthode nomme submitForm () :

    (...)public class MyInfoController { (...)

    @RequestMapping(method = RequestMethod.POST)

    Spring Livre Page 202 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    203

    public String submitForm( @ModelAttribute("userinfo") UserInfoData userInfo, BindingResult result) {

    User user = userManager.findUser(userInfo.getLogin()); user.setPassword(userInfo.getPassword()); user.setFirstName(userInfo.getFirstName()); user.setLastName(userInfo.getLastName()); user.setEmail(userInfo.getEmail()); userManager.updateUser(user);

    return "userinfo"; } (...)}

    Si une validation est mise en uvre, cette mthode a en charge la spcification de la vue daffi-chage du formulaire en cas dchec de validation. cet effet, elle doit prendre un paramtrede type BindingResult correspondant au rsultat du mappage. Ce paramtre pourra tre pass la mthode validate du validateur.

    Le code suivant illustre lintgration dun validateur () dans les traitements de soumissiondu contrleur :

    (...)public class MyInfoController { (...)

    @RequestMapping(method = RequestMethod.POST) public String submitForm( @ModelAttribute("userinfo") UserInfoData userInfo, BindingResult result) {

    (new RegisterValidator()).validate(userInfo, result); if (!result.hasErrors()) { User user = userManager.findUser(userInfo.getLogin()); user.setPassword(userInfo.getPassword()); user.setFirstName(userInfo.getFirstName()); user.setLastName(userInfo.getLastName()); user.setEmail(userInfo.getEmail()); userManager.updateUser(user); }

    return "userinfo"; } (...)}

    Lors de lutilisation dune vue fonde sur JSP/JSTL, les balises du taglib form de Springoffrent un support laffichage des donnes du formulaire ou des erreurs de validation. Sonutilisation est dtaille plus loin dans ce chapitre.

    Spring Livre Page 203 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    204

    Gestion des exceptions

    Par dfaut, Spring MVC fait remonter les diffrentes exceptions leves dans le conteneur deservlets. Il est cependant possible de modifier ce comportement par lintermdiaire de linter-face HandlerExceptionResolver, localise dans le package org.springframework.web.servlet :

    public interface HandlerExceptionResolver {

    ModelAndView resolveException(HttpServletRequest request,

    HttpServletResponse response, Object handler, Exception ex);

    }

    Le dveloppeur peut choisir dutiliser ses propres implmentations ou la classeSimpleMappingExceptionResolver du package org.springframework.web.servlet.handler fourniepar le framework. Cette dernire permet de configurer les exceptions traiter ainsi que lesvues qui leur sont associes. Lexception est alors stocke dans la requte avec la cl exception,ce qui la rend disponible pour un ventuel affichage.

    Support des formulaires sur plusieurs pagesSpring MVC supporte la mise en uvre dun formulaire sur plusieurs pages, la session Web devant dansce cas tre utilise. Le framework offre la possibilit de grer implicitement le stockage de lobjet de formu-laire ce niveau.Pour ce faire, il convient de prciser que lobjet de formulaire est stock en session par lintermdiaire delannotation SessionAttributes au niveau de la classe du contrleur. Cette annotation permet de spci-fier lidentifiant correspondant.Pour librer les ressources associes lors dun succs de la soumission du formulaire sur la dernire page, ilconvient dutiliser la mthode setComplete sur un objet de type SessionStatus. Un paramtre de ce typepeut tre pass directement en tant que paramtre de mthodes de traitement de requtes dans les contrleurs.Le code suivant est un exemple simple dutilisation de cette approche, savoir la configuration de lobjetde formulaire pour un stockage en session (), le passage dun paramtre de type SessionStatus ()et lutilisation de la mthode setComplete () sur cet objet :

    (...)@SessionAttributes("userinfo")public class MyInfoController { (...)

    @RequestMapping(method = RequestMethod.POST) public String submitForm( @ModelAttribute("userinfo") UserInfoData userInfo, BindingResult result, SessionStatus status) { (new RegisterValidator()).validate(userInfo, result); if (!result.hasErrors()) { status.setComplete(); (...) } (...) }}

    Spring Livre Page 204 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    205

    Cette implmentation se paramtre de la manire suivante :

    dataAccessFailure dataAccessFailure

    En rsum

    Spring MVC met en uvre une approche intressante pour les contrleurs MVC fonde surles annotations. Elle offre ainsi la possibilit de sabstraire de lAPI Servlet en laissant leframework raliser cette manipulation. Les signatures des points dentre des contrleurspeuvent tre adaptes en fonction des besoins et de lapproche souhaite.

    Au-del du cadre gnral propos par le framework, plusieurs dclinaisons sont possibles,comme lutilisation de contrleurs simples ou de formulaire pour la rcupration des param-tres de la requte, le remplissage du modle et la slection de la vue.

    Spring MVC et la gestion de la vueCette section se penche sur la faon dont sont traites les vues au sein du framework SpringMVC.

    Slection de la vue et remplissage du modle

    Spring MVC abstrait compltement la vue du contrleur, masquant ainsi sa technologie et samise en uvre. Au niveau du contrleur, le dveloppeur a la responsabilit de remplir lemodle avec les instances utilises dans la vue et de spcifier son identifiant.

    Diffrentes approches sont possibles pour cela, qui visent toutes faciliter lutilisation deSpring et la mise en uvre des contrleurs.

    La premire se fonde sur la classe ModelAndView dans le packageorg.springframework.web.servlet. Les donnes vhicules par cette classe sont utilises afinde slectionner la vue, la classe lui fournissant les donnes du modle. De ce fait, le dve-loppeur ne manipule plus lAPI Servlet pour remplir le modle et passer la main aux traite-ments de la vue.

    Spring Livre Page 205 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    206

    Cette classe doit tre utilise en tant que retour dune mthode de traitement de requtes anno-te avec RequestMapping. Une instance de la classe ModelAndView doit alors tre instancie etremplie ce niveau.

    Les donnes du modle sont stockes sous forme de table de hachage. Le code suivant donneun exemple de mise en uvre de ce mcanisme (), dans lequel lidentifiant todos corres-pond un nom symbolique de vue configur dans Spring MVC :

    @RequestMapping("/showTodos.do") public ModelAndView showTodos(HttpServletRequest request, HttpServletResponse response) throws Exception {

    String listId = (...);

    Map model = new HashMap(); model.put("defaultList", listId); return new ModelAndView("todos", model);}

    La seconde approche consiste en lutilisation de la classe Map ou Model ou ModelMap en tant queparamtre dune mthode de traitement annote avec RequestMapping. Dans ce cas, ce param-tre correspond lentit de stockage des lments du modle. Lidentifiant de la vue et cesdonnes sont dsormais dissocies.

    Si aucun identifiant de vue nest prcis, Spring MVC le dduit de lURI. Par exemple, si lavue se finit par /showTodos.do, lidentifiant dduit est showTodos. Il est nanmoins possible despcifier explicitement lidentifiant de la vue choisie en le faisant retourner sous forme dechane de caractres par la mthode.

    Le code suivant illustre lutilisation de la classe ModelMap pour grer les donnes du modle,ainsi que la manire de spcifier implicitement () et explicitement () lidentifiant de la vue :

    @RequestMapping("/welcome.do") public void welcome(ModelMap model) throws Exception { (...) //Lidentifiant de la vue est dduit //et correspond welcome}

    @RequestMapping("/showTodos.do") public String showTodos(ModelMap model) throws Exception { String listId = (...); model.addAttribute("defaultList", listId); //Lidentifiant de la vue est retourn return "todos"; }

    En parallle des mthodes de traitement des requtes, il est possible dajouter dautreslments dans le modle en utilisant le retour des mthodes annotes par ModelAttribute.Dans ce cas, le retour est automatiquement ajout au modle, avant mme que la mthode detraitement de la requte soit appele.

    Spring Livre Page 206 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    207

    Le code suivant illustre lutilisation de lannotation ModelAttribute () afin dajouter leretour dune mthode dans le modle et la vrification de la prsence de cet objet () dans lamthode de traitement dune requte :

    @ModelAttribute("user")public User getCurrentUser() { return userManager.getCurrentUser();}

    @RequestMapping("/showTodos.do") public String showTodos(ModelMap model) throws Exception { User user = (User)model.get("user"); (...) return "todos";}

    Configuration de la vueLa slection des vues dans Spring MVC est effectue par le biais dune implmentation delinterface ViewResolver dans le package org.springframework.web.servlet, comme lemontre le code suivant :

    public interface ViewResolver { View resolveViewName(String viewName, Locale locale);}

    Les sections qui suivent dtaillent les diffrentes implmentations de cette interface. Lafigure 7-6 illustre la hirarchie de ces classes et interfaces.

    Figure 7-6

    Hirarchie des implmentations de linterface ViewResolver

    ViewResolver

    AbstractCachingViewResolver

    UrlBasedViewResolver ResourceBundleViewResolver

    XmlViewResolver

    InternalResourceViewResolver AbstractTemplateViewResolver

    Spring Livre Page 207 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    208

    ResourceBundleViewResolver

    La premire implmentation, ResourceBundleViewResolver, correspond une configurationau cas par cas des vues utilises. Cette approche est particulirement intressante pour uneutilisation des vues fondes sur diffrentes technologies de prsentation. Sa configurationseffectue par le biais dun fichier de proprits contenant le paramtrage des diffrentesvues.

    Cette classe peut toutefois devenir vite contraignante si la majeure partie des vues utilisela mme technologie de prsentation. Les applications qui utilisent JSP/JSTL et des vuesPDF ou Excel pour afficher des tats sont un exemple de cette contrainte. Spring MVCoffre une solution fonde sur le chanage de ViewResolver pour optimiser la rsolution dece problme.

    Le code suivant montre de quelle manire configurer cette implmentation avec Spring MVC :

    La proprit basename permet de spcifier le fichier de proprits utilis, qui, dans lexemplesuivant, a pour nom views.properties :

    register_ok.class=org.springframework.web.servlet.view.RedirectViewregister_ok.url=welcome.action

    recover_password_ok.class =org.springframework.web.servlet.view.RedirectViewrecover_password_ok.url=welcome.action

    todo_lists_report.class=tudu.web.ShowTodoListsPdfView

    rssFeed.class=tudu.web.RssFeedViewrssFeed.stylesheetLocation=/WEB-INF/xsl/rss.xsl

    Ce fichier possde les configurations des vues de redirection ainsi que des vues fondes sur latechnologie XSLT et le framework iText.

    XmlViewResolver

    Les vues sont dfinies par lintermdiaire de cette implmentation au cas par cas, commeprcdemment, mais dans un sous-contexte de Spring. Lutilisation de toutes les fonctionnalits etmcanismes du framework est donc envisageable, de mme que linjection de dpendancessur la classe dimplmentation des vues.

    La configuration de cette implmentation se ralise de la manire suivante en utilisant pardfaut le fichier /WEB-INF/views.xml, tout en ncartant pas la possibilit den spcifier unautre par le biais de la proprit location :

  • Spring MVCCHAPITRE 7

    209

    class="org.springframework.web.servlet.view.XmlViewResolver">

    InternalResourceViewResolver

    Limplmentation InternalResourceViewResolver utilise les URI dans le but de rsoudre lesvues fondes, par exemple, sur les technologies JSP/JSTL. Ce mcanisme construit lURI partir de lidentifiant de la vue puis dirige les traitements vers dautres ressources gres parle conteneur de servlets, telles que des servlets ou des JSP, comme dans lexemple ci-dessous :

    Cette implmentation gnrale sapplique toutes les vues, except celles qui sont rsoluesprcdemment par une autre implmentation dans une chane de ViewResolver.

    Chanage dimplmentations de ViewResolver

    Spring MVC offre la possibilit de chaner les entits de rsolution des vues. Le frameworkparcourt dans ce cas la chane jusqu la dcouverte du ViewResolver appropri.

    Certaines de ces entits sappliquant toutes les vues, une stratgie par dfaut de rsolutiondes vues peut tre dfinie. Les implmentations fondes sur UrlBasedViewResolver, telles queInternalResourceViewResolver, fonctionnent sur ce principe.

    Lutilisation des vues fondes sur JSP/JSTL peut tre spcifie. Dautres vues, comme des redi-rections ou des vues gnrant des flux PDF ou Excel, sont dfinies ponctuellement dans un fichier.

    La figure 7-7 illustre un chanage dimplmentations de linterface de ViewResolver tir deTudu Lists.

    Sans cette fonctionnalit, la configuration de toutes les vues au cas par cas dans un fichierserait ncessaire, mme pour celles ne ncessitant pas de paramtrage spcifique.

    Lexemple suivant dcrit la configuration du chanage de ViewResolver :

    Spring Livre Page 209 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    210

    La proprit order permet de spcifier la position du ViewResolver dans la chane. Cet exemplemet en vidence que la classe InternalResourceViewResolver ne possde pas cette proprit,ce ViewResolver ne pouvant tre utilis quen fin de chane.

    Les technologies de prsentationSpring MVC propose plusieurs fonctionnalits qui simplifient normment la mise en uvredes technologies et frameworks de prsentation.

    Dans Spring MVC, une vue correspond une implmentation de linterface View du packageorg.springframework.web.servlet telle que dcrite dans le code suivant :

    public interface View { void render(Map model, HttpServletRequest request, HttpServletResponse response);}

    Cette interface possde plusieurs implmentations, localises dans le packageorg.springframework.web.servlet.view ou dans un de ses sous-packages.

    La figure 7-8 illustre la hirarchie de ses classes et interfaces.

    Figure 7-7

    Chanage de ViewResolver dans Tudu Lists

    XmlViewResolver

    Traitements des vues spcifies dans la configuration du rsolveur

    View

    Traitements de la vue en utilisant la technologie spcifie dans la

    configuration du rsolveur

    InternalResourceViewResolver

    Traitements par dfaut des vues en utilisant les technologies JSP /JSTL

    JstlView

    Traitements de la vue en utilisant les technologies JSP/JSTL

    Chanage de ViewResolver

    Spring Livre Page 210 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    211

    Vue de redirection

    Spring MVC dfinit un type de vue particulier afin de rediriger les traitements vers un URI ouune URL par lintermdiaire de la classe RedirectView. Elle se configure avec limplmenta-tion ResourceBundleViewResolver ou XmlViewResolver en imposant de dfinir la proprit url.

    Le code suivant donne un exemple de sa mise en uvre dans Tudu Lists :

    register_ok.class=org.springframework.web.servlet.view.RedirectViewregister_ok.url=welcome.action

    La proprit url permet de spcifier ladresse de redirection correspondante, laquelle est, dansnotre cas, relative au contexte de lapplication.

    La figure 7-9 illustre lenchanement des traitements afin dutiliser une vue de typeRedirectView.

    Figure 7-8

    Hirarchie des implmentations de linterface View

    View

    AbstractView

    AbstractUrlBasedView AbstractExcelView

    AbstractJExcelView

    AbstractPdfView

    AbstractXsltView

    InternalResourceView RedirectView

    JstlView TilesView

    Figure 7-9

    Enchanement des traitements pour la vue

    DispatchServlet

    Appelle la mthode render pour la vue dtermine par un ViewResolver.

    RedirectView

    Mthode render

    Appelle la mthode sendRedirect sur la requte en utilisant une proprit

    url.

    Spring Livre Page 211 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    212

    Cette vue peut tre configure plus rapidement et directement dans la configuration descontrleurs grce au prfixe redirect (), comme lillustre le code suivant :

    public class RestoreTodoListController { (...)

    @RequestMapping(method = RequestMethod.POST) public String submitForm( @ModelAttribute("restoredata") RestoreData restoreData, BindingResult result, SessionStatus status) { (...) return "redirect:showTodos.action"; }}

    Vue fonde sur JSP/JSTL

    Spring MVC fournit une vue fonde sur JSP/JSTL, dirigeant les traitements de la requte versune page JSP dont lURI est construit partir de lidentifiant de la vue.

    La figure 7-10 illustre lenchanement des traitements afin dutiliser une vue de type JstlView.

    Le dveloppeur prend uniquement en charge le dveloppement de la page JSP, tandis queSpring MVC a la responsabilit de mettre disposition dans la requte tout le contenu dumodle ainsi quventuellement des informations concernant le formulaire.

    Les balises et expressions JSTL peuvent tre utilises dune manire classique en utilisant lesdonnes du modle, ces dernires tant mises disposition par Spring MVC pour les pagesJSP. Pour une entre ayant pour cl maVariable dans le modle, la page JSP rcupre la valeurde sa proprit maPropriete correspondante de la manire suivante :

    Figure 7-10

    Enchanement des traitements pour la vue

    DispatchServlet

    Appelle la mthode render pour la vue dtermine par un ViewResolver.

    JstlView

    Mthode render

    Appelle la mthode forward sur une instance de RequestDispatcher.

    InternalResourceView

    Spring Livre Page 212 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    213

    Afin dutiliser les taglibs JSTL, des importations doivent tre places dans les pages JSP,comme dans le code suivant, tir de la page WEB-INF/jspf/header.jsp :

    Ainsi, laffichage de la liste des todos dans une page JSP se ralise de la manire suivante(cette liste ayant t spcifie dans le modle) :

    Affichage de la liste des todos:- ,

    Au niveau des formulaires, un taglib ddi permet de raliser le mappage entre les donnes duformulaire et les champs correspondants. Pour pouvoir lutiliser, limportation suivante (tirede la page WEB-INF/jspf/header.jsp) doit tre place dans les pages JSP :

    Le tableau 7-4 rcapitule les balises proposes par ce taglib pour construire des formulaires.

    Tableau 7-4. Balises du taglib form de gestion de formulaires

    Balise Description

    checkbox Dfinit un lment de formulaire de type case cocher pour un attr ibut du Bean de formulaire.

    checkboxes Dfinit un ensemble dlments de formulaire de type case cocher pour un attr ibut de formu-laire. Linitialisation des valeurs des lments se ralise par tir dune liste prsente dans lemodle.

    errors Affiche les erreurs survenues lors de la soumission dun formulaire un niveau global ou parchamp.

    form Dfinit un formulaire et le rattache ventuellement un Bean de formulaire.

    hidden Dfinit un lment de formulaire cach pour un attribut du Bean de formulaire.

    input Dfinit un lment de formulaire de type texte pour un attribut du Bean de formulaire.

    option Dfinit un lment de liste.

    options Dfinit un ensemble dlments de liste. Linitialisation des valeurs des lments se ralise par-tir dune liste prsente dans le modle.

    password Dfinit un lment de formulaire de type mot de passe pour un attr ibut du Bean de formulaire.

    radiobutton Dfinit un lment de formulaire de type bouton radio pour un attribut du Bean de formulaire.

    radiobuttons Dfinit un ensemble dlments de formulaire de type bouton radio pour un attribut du Bean de formu-laire. Linitialisation des valeurs des lments se ralise partir dune liste prsente dans le modle.

    select Dfinit un lment de formulaire de type liste pour un attribut du Bean de formulaire. Cette balisedoit tre utilise conjointement avec les balises option et options afin de spcifier les valeursde la liste.

    textarea Dfinit un lment de formulaire de type zone de texte pour un attribut du Bean de formulaire.

    Spring Livre Page 213 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    214

    Ces balises permettent de rfrencer les attributs dun Bean de formulaire mis dispositiondans le modle laide des techniques dcrites prcdemment la section Contrleur degestion de formulaire .

    La correspondance entre le formulaire et le Bean de formulaire se ralise au niveau de labalise form par lintermdiaire du champ modelAttribute, qui spcifie le nom de lentre dansle modle.

    Lutilisation des balises du taglib form permet dinitialiser automatiquement les champs duformulaire avec les donnes du formulaire et dafficher les ventuelles erreurs survenues. Lecode suivant montre lutilisation de cette balise dans la page JSP WEB-INF/jsp/user_info.jspde ltude de cas :

    (...)

    La balise form permet de dfinir lidentifiant de llment dans le modle correspondant auBean de formulaire en se fondant sur lattribut modelAttribute (). Elle permet galement dedlimiter les lments du formulaire.

    Au sein du formulaire, les champs correspondant aux attributs du Bean de formulaire peuventtre spcifis. La correspondance entre le champ et lattribut correspondant se ralise parlintermdiaire de lattribut path de la balise. Dans notre exemple, la balise input () portesur la proprit firstName du Bean de formulaire ayant pour nom userinfo.

    Laffichage des erreurs, gnrales ou associes un champ, se ralise par lintermdiaire de labalise errors. Lattribut path permet de prciser les erreurs afficher. Avec une valeur *,toutes les erreurs relatives au formulaire sont affiches. Avec le nom dun champ, comme danslexemple prcdent (), lventuelle erreur correspondant au champ est affiche.

    Autres vues

    Spring MVC apporte des supports pour toutes sortes de vues qui ne sont pas ncessairementfondes sur des redirections internes au conteneur de servlets (mthode forward) ou des redi-rections de requtes (mthode sendRedirect), notamment des classes abstraites de base pourles technologies suivantes :

    gnration de documents (PDF, Excel, etc.) ;

    gnration de rapports avec Jasper Reports ;

    Spring Livre Page 214 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    215

    gnration de prsentations fondes sur des templates (Velocity, FreeMarker) ;

    gnration de prsentations fondes sur les technologies XML.

    Concernant les vues gnrant des documents et celles fondes sur les technologies XML, leframework Spring MVC instancie les ressources reprsentant le document par le biais demthodes gnriques. Il dlgue ensuite les traitements une mthode de la vue afin de construirele document ou de convertir le modle dans une technologie donne. Le framework reprendensuite en main ces traitements afin dexcuter ventuellement une transformation puisdcrire le rsultat sur le flux de sortie.

    La figure 7-11 illustre lenchanement des traitements dune vue gnrant un document avecle support PDF de Spring MVC.

    Dans lexemple dcrit la figure 7-11, la classe MyView tend la classe abstraiteAbstractPdfView du package org.springframework.web.servlet.view afin dimplmenter lamthode abstraite buildPdfDocument. Cest pourquoi la classe MyView ne contient plus que lestraitements spcifiques lapplication pour la construction du document, son instanciation etson renvoi au client tant encapsuls dans la classe AbstractPdfView.

    Figure 7-11

    Enchanement des traitements de la vue

    AbstractPdfView MyView

    Cration du document PDF, initialisation du document en

    utilisant les API iText

    Appel de la mthode buildPdfDocument

    Positionnement des en-ttes HTTP

    Ecriture du document sur le flux de sortie

    Construction du document PDF

    Spring Livre Page 215 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    216

    En rsum

    Approfondissant les principes de gestion de la prsentation au sein du framework SpringMVC, nous avons vu que ce dernier met en uvre des mcanismes de mise en relation dunidentifiant et de sa vue, tout en favorisant la coexistence de vues fondes sur diverses tech-nologies. Le framework permet lutilisation dun nombre important de technologies deprsentation.

    La mise disposition des donnes prsentes dans le modle pour les vues est ralise automa-tiquement par le framework.

    Support de REST (Representational State Transfer)La version 3.0 de Spring introduit le support natif de la technologie REST afin dutiliser lesURI conformes ce format tout en suivant le modle de programmation de Spring MVCfond sur les annotations.

    Avec la technologie REST, les paramtres font partie intgrante de lURI, comme lillustre lecode suivant avec un exemple dURI contenant le paramtre id :

    ///{id}

    Spring 3.0 offre non seulement la possibilit dcrire des contrleurs Web REST, maispropose aussi un composant client permettant deffectuer des requtes REST, le RestTemplate.

    Contrleur Web REST

    Spring MVC offre la possibilit de passer en paramtres des mthodes des contrleurs desvaleurs en se fondant sur lannotation PathVariable. Cette dernire fonctionne dune manire

    La technologie REST

    Cette technologie correspond une manire de construire des applications pour les systmes distribus.REST nest pas un protocole ou un format, mais correspond au style architectural original du Web, bti surles principes simples suivants : LURI est trs important puisque, dans ce contexte, connatre ce dernier doit suffire pour accder laressource. Il nest plus besoin de spcifier des paramtres supplmentaires. De plus, la manipulation de laressource se fonde sur lutilisation des oprations du protocole HTTP (GET, POST, PUT et DELETE,essentiellement). Chaque opration est autosuffisante, et aucun tat nest stock au niveau de la ressource. Le client a laresponsabilit du stockage de cet tat. En parallle, la technologie utilise des standards hypermdias telsque HTML ou XML afin de raliser les liens vers dautres ressources et dassurer ainsi la navigation danslapplication. Il est possible de mettre en uvre des architectures orientes services de manire simple en utilisantdes services Web interapplicatifs. La technologie REST propose ainsi une solution de rechange intres-sante et plus simple au mode RPC et, dans la plupart des cas, SOAP.

    Spring Livre Page 216 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    217

    similaire lannotation RequestParam en rfrenant les paramtres prsents dans ladressedaccs, comme lillustre le code suivant () :

    @RequestMapping(value = "/todo/{format}/{todoId}")public ModelAndView getTodo(@PathVariable String format, @PathVariable String todoId) { (...)}

    Avec REST, il est dsormais possible dutiliser dautres mthodes HTTP que celles utiliseshabituellement dans les navigateurs par les applications Web classiques, savoir les mthodesGET et POST. Dans ce contexte, lappel dune ressource ralisant la suppression dune entitseffectue avec la mthode DELETE. La mthode correspondante du contrleur doit spcifierla mthode HTTP daccs au niveau de lannotation RequestMapping, comme dans le codesuivant () :

    @RequestMapping( value = "/todo/{todoId}", method = RequestMethod.DELETE)public void deleteTodo(@PathVariable String todoId, HttpServletResponse response) { todoManager.remove(todoId); // pas de rendu de vue response.setStatus(HttpServletResponse.SC_OK);}

    Lappel de cette mthode peut se raliser dans une page JSP par le biais de la balise form dutaglib form de Spring, comme dans le code suivant () :

    En gardant le mme modle de programmation que celui de Spring MVC, le support REST deSpring permet de mettre en uvre REST de manire intressante. Tous les mcanismes deSpring MVC sont utilisables dans ce contexte, contribuant dautant la simplicit de mise enuvre de cette technologie.

    Le RestTemplate

    Le RestTemplate est la classe centrale du support client REST dans Spring. Il permet deffec-tuer des requtes HTTP selon les diffrentes mthodes du protocole, tout en facilitant lagestion des rponses, avec la possibilit de transformer directement le flux de rponses enobjets Java.

    Le RestTemplate fonctionne suivant la philosophie des templates daccs aux donnes deSpring, dont les principes sont prsents au chapitre 10. Il peut nanmoins tre utilis directe-ment, sans connatre ces principes sous-jacents, lessentiel consistant savoir que le

    Spring Livre Page 217 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    218

    RestTemplate gre les connexions HTTP et laisse le dveloppeur se concentrer sur le codeapplicatif.

    Le RestTemplate peut tre instanci de faon programmatique, mais il est plus judicieux de ledclarer dans le contexte Spring, afin de profiter de linjection de dpendances, notammentpour de la configuration plus fine :

    Le RestTemplate est dclar comme tout autre Bean, avec la classe correspondante (). Poureffectuer les accs HTTP, le RestTemplate utilise une abstraction, la ClientHttpRequest-Factory, que lon positionne avec la proprit requestFactory (). Nous utilisons dans notreexemple une implmentation fonde sur la bibliothque Jakarta Commons HttpClient, qui offredes possibilits intressantes de configuration (authentification, pool de connexions, etc.).

    Une fois configur, le RestTemplate peut tre utilis pour rcuprer le rsultat dune requteHTTP, par exemple pour appeler la mthode getTodo du contrleur REST de la sectionprcdente :

    String xml = restTemplate.getForObject( "http://localhost:8080/rest/todo/{format}/{todoId}", String.class, "xml","1");

    La mthode getForObject du RestTemplate prend en premier paramtre lURL appeler ().On remarque lutilisation de la syntaxe {nomParametre} pour indiquer les diffrentsparamtres ; dans notre cas, le format souhait de la rponse (XML, HTML ou PDF) et liden-tifiant du Todo. Le deuxime paramtre de getForObject est la classe de retour attendue ().Le RestTemplate est en effet capable de transformer le flux de la rponse en un objet Java.

    Par dfaut, les transformations sont limites (chanes de caractres ou tableau doctets), maisnous verrons par la suite que ce mcanisme est paramtrable. Dans notre exemple, nous nouscontentons de rcuprer la rponse sous forme de chane de caractres. La mthodegetForObject accepte en derniers paramtres une liste variable dobjets, qui constituent lesparamtres insrer dans la requte HTTP ().

    La combinaison de lURL demande et des paramtres fera que lURL appele sera lasuivante :

    http://localhost:8080/rest/todo/xml/1

    La rponse est bien sr gre par notre contrleur REST, qui renvoie pour une telle requte unflux XML :

    1

    Spring Livre Page 218 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    219

    todo 1 1 true true

    La variable locale xml dans lexemple ci-dessus contiendra donc ce code XML. Il est impor-tant de noter que lutilisation du RestTemplate nest pas limite linterrogation de contr-leurs REST implments par Spring MVC. La rponse pourrait tout aussi bien tre gnrepar un autre type de contrleur Web, dans un langage diffrent de Java.

    Nous venons de voir comment faire une requte GET (au sens HTTP du terme) avec leRestTemplate. Celui-ci propose une API complte pour effectuer dautres types de requtes,suivant les mthodes du protocole HTTP.

    Nous pouvons effectuer une requte DELETE, par exemple, sur la mthode deleteTodo denotre contrleur :

    restTemplate.delete( "http://localhost:8080/rest/todo/{todoId}", "1");

    Cet appel va supprimer le Todo didentifiant 1. Aucune rponse nest attendue.

    Le tableau 7-5 rcapitule les principales mthodes disponibles dans le RestTemplate. Remar-quez lexistence de la mthode execute, qui, moyennant une utilisation plus complexe, permetde construire des requtes et dexploiter les rponses pour des besoins avancs, selon le prin-cipe des templates Spring.

    Nous avons vu dans notre premire utilisation du RestTemplate quil facilitait grandementlappel de services REST, mais que sa gestion de la rponse tait relativement limite : nousavons rcupr un document XML sous forme de chane de caractres. Cette rponse contientles informations demandes, mais ncessite une exploitation (analyse du code XML), quisavre fastidieuse si elle doit tre faite au niveau de lappel. Lidal serait de rcuprer lobjetmtier attendu, cest--dire une instance de Todo, le RestTemplate prenant sa charge la trans-formation.

    Tableau 7-5. Mthodes du RestTemplate

    Mthode HTTP Mthode du RestTemplate

    DELETE delete(String, String, )

    GET delete(String, Class, String, )

    HEAD headForHeaders(String, String )

    OPTIONS optionsForAllow(String, String )

    POST postForLocation(String, Object, String )

    PUT put(String, Object, String )

    Toutes execute(String, HttpMethod, RequestCallback, ResponseExtractor, String )

    Spring Livre Page 219 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    220

    Le RestTemplate propose un mcanisme de convertisseur qui permet de contrler trs fine-ment la conversion des objets Java qui lui sont passs ainsi que ceux quil renvoie. Nous allonsici nous intresser aux objets renvoys, en convertissant le flux XML reu prcdemment enun objet Todo.

    Cette conversion nous permettra deffectuer lappel suivant, pour lequel nous demandons etrcuprons directement un Todo, plutt quun document XML :

    Todo todo = restTemplate.getForObject( "http://localhost:8080/rest/todo/{format}/{todoId}", Todo.class, "xml","1");

    Pour arriver ce rsultat, il faut implmenter un HttpMessageConverter, qui va se charger de laconversion de la rponse, puis lassigner au RestTemplate.

    Voici le code de limplmentation de TodoHttpMessageConverter :

    package tudu.web.rest;(...)import org.springframework.http.HttpInputMessage;import org.springframework.http.HttpOutputMessage;import org.springframework.http.MediaType;import org.springframework.http.converter.HttpMessageConverter;import tudu.domain.model.Todo;import com.thoughtworks.xstream.XStream;

    public class TodoHttpMessageConverter implements HttpMessageConverter {

    public List getSupportedMediaTypes() { return Collections.singletonList( new MediaType("text","xml") ); }

    public boolean supports(Class

  • Spring MVCCHAPITRE 7

    221

    Le rle dun HttpMessageConverter est deffectuer des transformations dobjets Java vers desmessages HTTP et inversement. Il doit donc indiquer le type de mdia quil est capable degrer () : dans notre cas les rponses de type text/xml, ainsi que la hirarchie de classesquil peut convertir (), cest--dire des Todos.

    La mthode read nous intresse particulirement, car cest elle qui se charge de la transforma-tion de la rponse en Todo. Nous recevons ici une reprsentation XML dun Todo, et nous utili-sons XStream pour la convertir en objet Java (). XStream prsente lintrt dtre trssimple dutilisation et concis, mais tout autre mcanisme de dsrialisation aurait pu tout aussibien convenir. Lopration inverse, qui consiste transformer lobjet Java en message HTTP,ne nous intressant pas, elle nest pas implmente ().

    Le convertisseur tant crit, il faut maintenant le positionner au sein du RestTemplate, grce sa proprit messageConverters, qui contient la liste de ses diffrents convertisseurs :

    (...)

    Un RestTemplate dispose de convertisseurs positionns par dfaut, qui grent les conver-sions sous forme de chanes de caractres ou de tableau doctets. Il faut les positionnerexplicitement ds que nous paramtrons la proprit messageConverters, afin que ces cassimples soient toujours grs (). Notre convertisseur de Todo est lui paramtr aurepre .

    Le mcanisme de convertisseurs apporte au RestTemplate une extensibilit et une adaptabilittrs intressantes, lui permettant de grer la conversion des messages HTTP en objets Java,afin dobtenir un code applicatif le plus pur possible.

    En rsumSpring 3.0 apporte un support REST Spring MVC. Il devient alors possible dimplmenterdes contrleurs REST en suivant le modle de programmation de Spring MVC, fond sur lesannotations.

    Le support client nest pas en reste, avec le RestTemplate, qui propose une API trs simple etextensible afin dinterroger des services REST (indpendamment de leur technologie) etdexploiter au mieux leur rponse.

    Spring Livre Page 221 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    222

    Mise en uvre de Spring MVC dans Tudu ListsLes principaux concepts et composants de Spring MVC ayant t introduits, nous pouvonspasser leur mise en pratique dans notre tude de cas.

    Configuration des contextesLe premier contexte renvoie lapplication Web. Il est charg avec le support de la classeContextLoaderListener en utilisant les fichiers dont le nom correspond au pattern /WEB-INF/applicationContext*.xml.Le second contexte est utilis par Spring MVC et est charg par la servlet DispatcherServleten utilisant le fichier action-servlet.xml localis dans le rpertoire WEB-INF. Les diffrentesentits relatives Spring MVC sont dfinies dans ce fichier.

    Cette servlet est configure dans le fichier web.xml de lapplication Web, comme lillustre lecode suivant :

    (...) action org.springframework.web.servlet.DispatcherServlet 1

    action *.action (...)

    Dans le fichier action-servlet.xml suivant, lapproche fonde sur les annotations a t activeen se fondant sur la balise component-scan () de lespace de nommage context (seuls lescontrleurs localiss dans les packages dont le nom commence par tudu.web tant utiliss) :

    (...)

    Spring Livre Page 222 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    223

    Commons Validator

    Le projet Spring Modules offre le support de Commons Validator, le framework dApachevisant spcifier les rgles de validation par dclaration communment utilis avec Struts.

    Commons Validator se configure de la manire suivante dans le cadre de Spring MVC :

    /WEB-INF/validator-rules.xml /WEB-INF/validation.xml

    Dans chaque contrleur de gestion de formulaire, le Bean beanValidator doit tre inject parlintermdiaire de lannotation Autowired. Le nom du Bean de formulaire utilis par le contrleurpermet de dterminer la rgle utiliser de la configuration de la validation WEB-INF/valida-tion.xml. La mthode validate de ce Bean est ensuite utilise afin de raliser la validation.

    Implmentation des contrleurs

    Au travers de lapplication Tudu Lists, diffrents mcanismes et types de contrleurs sontimplments par le biais des annotations RequestMapping, ModelAttribute et InitBinder dcri-tes dans les sections prcdentes.

    Les sections suivantes se penchent sur la faon dont sont mis en uvre des contrleurs entre multiple et de formulaire ralisant respectivement un affichage de donnes et unegestion de formulaire HTML. La prsentation associe ces deux contrleurs utilise les tech-nologies JSP/JSTL.

    Contrleur simple

    Le contrleur ShowTodosAction du package tudu.web dispose de traitements pour afficher lestodos dune liste. Comme lillustre lextrait de code ci-aprs, il utilise Spring MVC laidedes lments suivants :

    Annotation Controller au niveau de la classe () afin de prciser que cette dernire joue lerle dun contrleur dans Spring MVC.

    Annotation RequestMapping au niveau de la mthode showTodos () afin de dfinir le pointdentre. Plusieurs points dentre peuvent tre spcifis ce niveau.

    Spring Livre Page 223 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    224

    Annotation RequestParam afin de rcuprer directement en tant que paramtres du pointdentre les paramtres de la requte Web. Dans notre cas, le paramtre optionnel listId() est pris directement dans la requte sil est prsent. Dans le cas contraire, sa valeur vautnull.

    Paramtre de type ModelMap () afin de manipuler les donnes du modle. Des ajouts dansce dernier peuvent tre raliss par lintermdiaire de la mthode addAttribute de la classe().

    Type de retour afin de prciser la vue utilise pour prsenter les donnes ().

    @Controllerpublic class ShowTodosController { (...) @RequestMapping("/secure/showTodos.action") public String showTodos( @RequestParam(value="listId", required=false) String listId, ModelMap model ) {

    log.debug("Execute show action"); Collection todoLists = new TreeSet( userManager.getCurrentUser().getTodoLists());

    if (!todoLists.isEmpty()) { if (listId != null) { model.addAttribute("defaultList", listId); } else { model.addAttribute("defaultList", todoLists.iterator().next().getListId()); } } return "todos"; }}

    Aucune configuration nest requise dans le fichier WEB-INF/action-servlet.xml pour lecontrleur. Les configurations relatives Spring MVC () et linjection de dpendances() se ralise directement dans la classe par lintermdiaire dannotations, comme lillustrele code suivant :

    @Controllerpublic class ShowTodosController { @Autowired private UserManager userManager;

    (...)

    @RequestMapping("/secure/showTodos.action") public String showTodos(

    Spring Livre Page 224 Lundi, 15. juin 2009 5:57 17

  • Spring MVCCHAPITRE 7

    225

    @RequestParam(value="listId", required=false) String listId, ModelMap model (...) }}

    La manire daccder aux points dentre du contrleur est dfinie dans les annotationsRequestMapping. Aucune configuration supplmentaire nest ncessaire. Dans le cas prcdent, lecontrleur ShowTodosController est accessible partir de lURI /secure/showTodos.action.

    Cette tude de cas met galement en pratique le mcanisme de chanage de ViewResolver.Ainsi, retrouve-t-on dans le fichier /WEB-INF/action-servlet.xml la configuration deplusieurs ViewResolver :

    Le premier est implment par la classe ResourceBundleViewResolver, qui utilise le fichierde proprits views.properties afin de configurer les vues.

    Le deuxime est implment par la classe XmlViewResolver, qui utilise le fichier /WEB-INF/views.xml pour configurer les vues.

    Le dernier est implment par la classe InternalResourceViewResolver, qui se fonde, dansnotre cas, sur une vue JSP/JSTL. Il constitue la stratgie de rsolution par dfaut et estutilis dans le cas o un identifiant de vue ne peut tre rsolu par les deux entits prcdem-ment dcrites.

    La figure 7-12 illustre cette chane en soulignant les identifiants des vues configures dans lesdeux premiers ViewResolver.

    Le contrleur utilise la vue todos qui est rsolue par le dernier ViewResolver et corresponddonc la page JSP todos.jsp localise dans le rpertoire /WEB-INF/jsp/.

    Contrleur de gestion de formulaire

    La mise en uvre dun contrleur de gestion de formulaire nest gure plus complexe quecelle dun contrleur simple : un Bean est utilis pour les donnes du formulaire, et deuxpoints dentre doivent tre dfinis, un pour le chargement du formulaire, lautre pour sa vali-dation.

    Figure 7-12

    Chanage des ViewResolver dans Tudu Lists

    ViewResolver1(views.properties)

    ViewResolver2(views.xml)

    Vues : register_ok, recover_password_ok,

    rssFeed

    Vues : todol_lists_report, backup

    ViewResolver3(JSP / JSTL)

    Vues : toutes les pages JSP

    Spring Livre Page 225 Lundi, 15. juin 2009 5:57 17

  • Les frameworks de prsentationPARTIE II

    226

    Dtaillons le contrleur MyInfosController du package tudu.web, qui permet de modifier lesinformations dun utilisateur de lapplication.

    Comme lillustre lextrait de code ci-aprs, ce contrleur utilise Spring MVC laide deslments suivants :

    Annotations Controller et RequestMapping au niveau de la classe afin de dfinir la classe entant que contrleur et lURI daccs ce dernier ().

    Mthode showForm () appele par lintermdiaire dune mthode GET et configure aveclannotation RequestMapping. Cette mthode a la responsabilit de charger les donnes duformulaire.

    Mthode submitForm () appele afin de traiter les donnes soumises par le formulaireavec la mthode HTTP POST et configure avec lannotation RequestMapping.

    Utilisation explicite de la validation Commons Validator dans le corps de la mthodesubmitForm ().

    Spcification des vues utilises pour laffichage suite la soumission du formulaire parlintermdiaire des retours des deux mthodes prcdentes ().

    @Controller@RequestMapping("/secure/myinfos.action")public class MyInfoController { (...) @RequestMapping(method = RequestMethod.GET) public String showForm(HttpServletRequest request, ModelMap model) { String login = request.getRemoteUser(); User user = userManager.findUser(login); UserInfoData data=new UserInfoData(); data.setPassword(user.getPassword()); data.setVerifyPassword(user.getPassword()); data.setFirstName(user.getFirstName()); data.setLastName(user.getLastName()); data.setEmail(user.getEmail()); model.addAttribute("userinfo", data); return "userinfo"; }

    @RequestMapping(method=RequestMethod.POST) public String submitForm(