Вы находитесь на странице: 1из 49

Spring

par la pratique
ition
e
2 d 2.5
g
Sprin .0
et 3
Arnaud

Cogolugnes

Thierry

Templier

Julien
Jean-Philippe

de

Dubois
Retaill

avec la contribution
Sverine Templier Roblou
et de Olivier Salvatori

Groupe Eyrolles, 2006, 2009,


ISBN : 978-2-212-12421-7

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

7
Spring MVC
La mise en pratique du patron de conception MVC (Model View Controller) offre une
meilleure structuration du tiers de prsentation des applications Java EE en dissociant les
proccupations de dclenchement des traitements de la construction de la prsentation proprement dite. Les principaux frameworks MVC implmentent le type 2 de ce patron, qui instaure
un point dentre unique ayant pour mission daiguiller les requtes vers la bonne entit de
traitement.
Le framework Spring offre une implmentation innovante du patron MVC par le biais dun
framework nomm Spring MVC, qui profite des avantages de linjection de dpendances (voir
chapitres 2 et 3) et qui, depuis la version 2.5, offre une intressante flexibilit grce aux annotations Java 5. Ce module permet ds lors de sabstraire de lAPI Servlet de Java EE, les informations souhaites tant automatiquement mises disposition en tant que paramtres des
mthodes des contrleurs.
De plus, partir de la version 3.0, Spring MVC intgre un support permettant de grer la technologie REST, les URL possdant la structure dcrite par cette dernire tant exploitable en
natif.
Le prsent chapitre passe en revue les fonctionnalits et apports de ce module, qui met en
uvre les principes gnraux du framework Spring, lesquels consistent masquer lAPI
Servlet et simplifier les dveloppements dapplications Java EE tout en favorisant leur structuration et leur flexibilit.

Implmentation du pattern MVC de type 2 dans Spring


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

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

184

Les frameworks de prsentation


PARTIE II

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

Fonctionnement du patron MVC 2


Le patron MVC est communment utilis dans les applications Java/Java EE pour raliser la
couche de prsentation des donnes aussi bien dans les applications Web que pour les clients
lourds. Lorsquil est utilis dans le cadre de Java EE, il sappuie gnralement sur lAPI
servlet 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 nous
concentrerons 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 interactions
lors du traitement dune requte.

Contrleur

Contrleur frontal

Entit de traitement

Aiguillage des
requtes vers la
bonne entit de
traitement

Ralise les
traitements de la
requte
Modle

Objet
Objet
Objet
Contient les
donnes
prsenter
Vue
Fichier

Classe

Construite la vue
avec un pseudo
template afin
dafficher les
donnes prsenter

Construit la vue en
Java afin dafficher
les donnes
prsenter

Figure 7-1

Entits mises en uvre dans le patron MVC de type 2

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

Spring MVC
CHAPITRE 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 traitements de prsentation. Cette entit est indpendante des API techniques et est constitue
uniquement de Beans Java.
Vue. Permet la prsentation des donnes du modle. Il existe plusieurs technologies de
prsentation, parmi lesquelles JSP/JSTL, XML, les moteurs de templates Velocity et FreeMarker ou de simples classes Java pouvant gnrer diffrents types de formats.
Contrleur. Gre les interactions avec le client tout en dclenchant les traitements appropris. Cette entit interagit directement avec les composants de la couche service mtier et
a pour responsabilit la rcupration des donnes mises disposition dans le modle. Lors
de la mise en uvre du type 2 de ce patron, cette partie se compose dun point dentre
unique pour toute lapplication et de plusieurs entits de traitement. Ce point dentre
unique 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 sont
spcifiques 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 en
charge le dveloppement et la configuration des entits de traitements et des vues choisies.

Principes et composants de Spring MVC


Le framework Spring fournit des intgrations avec les principaux frameworks MVC ainsi que
sa propre implmentation. Forts de leur exprience dans le dveloppement dapplications Java
EE, ses concepteurs considrent que linjection de dpendances offre un apport de taille pour
concevoir 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 des
contextes applicatifs de manire transparente ainsi que des intgrations avec dautres
frameworks 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 de
bnficier de toutes les fonctionnalits du framework Spring, notamment au niveau de la
rsolution 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 logique
des diffrents composants de lapplication. Par exemple, les composants des services
mtier et des couches infrieures nont pas accs ceux du MVC.

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

186

Les frameworks de prsentation


PARTIE II

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 contrleurs MVC se ralisent par lintermdiaire dannotations. Par ce biais, Spring MVC permet
de masquer lutilisation de lAPI servlet et favorise la mise en uvre des tests unitaires ce
niveau. Lapproche fonde sur les classes dimplmentation de contrleurs est dsormais
dprcie.
Gestion des formulaires en se fondant sur les annotations relatives aux contrleurs afin non
seulement de charger et dafficher les donnes du formulaire, mais galement de grer leur
soumission. Ces donnes sont utilises pour remplir directement un Bean sans lien avec
Spring MVC, qui peut tre valid si ncessaire. Des mcanismes de mappage et de conversion
des donnes sont intgrs et extensibles selon les besoins.
Abstraction de limplmentation des vues par rapport aux contrleurs permettant de
changer de technologie de prsentation sans impacter le contrleur.
Pour mettre en uvre ces principes et composants, Spring MVC sappuie sur les entits illustres la figure 7-2. Le traitement dune requte passe successivement par les diffrentes entits
en commenant par la servlet DispatcherServlet et en finissant par la vue choisie.

DispatcherServlet

HandlerMapping

Controller

ViewResolver

View

Contrleur faade

Aiguillage 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
Contexte de Spring MVC

Contexte de l'application Web

Contexte partag (facultatif)

Figure 7-2

Entits de traitement des requtes de Spring MVC

Les principaux composants de Spring MVC peuvent tre rpartis en trois groupes, selon leur
fonction :
Gestion du contrleur faade et des contextes applicatifs. Permet de spcifier les fichiers des
diffrents contextes ainsi que leurs chargements. Le contrleur faade doit tre configur de
faon spcifier laccs lapplication.

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

Spring MVC
CHAPITRE 7

187

Gestion des contrleurs. Consiste configurer la stratgie daccs aux contrleurs, ainsi
que leurs diffrentes classes dimplmentation et leurs proprits. Laiguillage se configure
dsormais directement dans les classes mettant en uvre des contrleurs en se fondant sur
des annotations. Ces dernires permettent galement de mettre facilement disposition les
donnes prsentes dans la requte, la session et le modle.
Gestion des vues. Consiste configurer la ou les stratgies de rsolution des vues ainsi que
les frameworks ou technologies de vue mis en uvre.

Initialisation du framework Spring MVC


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

Gestion des contextes


Le framework Spring permet de charger automatiquement les contextes applicatifs en utilisant
les mcanismes des conteneurs de servlets.
Dans le cadre dapplications Java EE, une hirarchie de contextes est mise en uvre afin de
regrouper et disoler de manire logique les diffrents composants. De la sorte, un composant
dune couche ne peut accder celui dune couche suprieure.

Contexte applicatif Spring


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

Le framework Spring offre une hirarchie pour les trois contextes suivants :
Contexte racine. Ce contexte est trs utile pour partager des objets dune mme bibliothque entre plusieurs modules dune mme application Java EE pour un mme chargeur de
classes.
Contexte de lapplication Web. Stock dans le ServletContext, ce contexte doit contenir la
logique mtier ainsi que celle de laccs aux donnes.
Contexte du framework MVC. Gr par le contrleur faade du framework, ce contexte doit
contenir tous les composants relatifs au framework MVC utilis.

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

188

Les frameworks de prsentation


PARTIE II

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

Hirarchie des contextes de


Spring pour une application
Web

Contexte racine
Singleton

Contexte WebApp

Contexte WebApp
ServletContext

Contexte MVC

Contexte MVC
Servlet

La mise en uvre du contexte de lapplication Web est obligatoire, tandis que celle du
contexte 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 contexte
racine.
Linitialisation du contexte de lapplication Web, que nous dtaillons dans ce chapitre, est
indpendante 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 la


spcification servlet permettant de configurer et dinitialiser ce contexte au dmarrage et de le
finaliser larrt de lapplication Web.
Cette fonctionnalit est utilisable avec un conteneur de servlets supportant au moins la
version 2.3 de la spcification. Cet observateur paramtre les fichiers de configuration XML
du contexte en ajoutant les lignes suivantes dans le fichier web.xml de lapplication :
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

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

Spring MVC
CHAPITRE 7

189

Chargement du contexte de Spring MVC

La configuration tout comme le chargement de ce contexte sont lis ceux de la servlet du


contrleur faade de Spring MVC. Prcisons que, par dfaut, cette dernire initialise un
contexte applicatif fond sur un fichier <nom-servlet>-servlet.xml, lequel utilise le nom de la
servlet prcdente pour <nom-servlet>. Ce fichier se situe par dfaut dans le rpertoire WEBINF ; la valeur de <nom-servlet> est spcifie grce la balise servlet-name.
Dans notre tude de cas, la servlet de Spring MVC sappelle tudu. Le fichier tudu-servlet.xml
contient les diffrents composants utiliss par ce framework, comme les contrleurs, les vues
et les entits de rsolution des requtes et des vues.
Nous pouvons personnaliser le nom de ce fichier laide du paramtre dinitialisation
contextConfigLocation de la servlet. Le code suivant montre comment spcifier un fichier
mvc-context.xml pour le contexte de Spring MVC par lintermdiaire du paramtre prcdemment cit () :
<web-app>
(...)
<servlet>
<servlet-name>tudu</servlet-name>
(...)
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-context.xml</param-value>
</init-param>
</servlet>
</web-app>

Initialisation du contrleur faade


Le fait que le framework Spring MVC implmente le patron MVC de type 2 entrane quil
met en uvre un contrleur faade pour diriger les traitements vers des classes dsignes par
le terme Controller dans Spring MVC.
Le contrleur faade
Cette entit correspond lunique point daccs de lapplication Web. Son rle est de rediriger les traitements vers le bon contrleur en se fondant sur ladresse daccs pour traiter la requte. Dans le cas
dapplications Web, ce contrleur est implment par le biais dune servlet, qui est gnralement fournie
par le framework MVC utilis.

Ce contrleur faade est implment par le biais de la servlet DispatcherServlet du package


org.springframework.web.servlet, cette dernire devant tre configure dans le fichier WEBINF/web.xml.
Le mappage de la ressource () est dfini au niveau du conteneur de servlets dans le fichier
web.xml localis dans le rpertoire WEB-INF. Spring ne pose aucune restriction ce niveau,
comme lillustre le code suivant :

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

190

Les frameworks de prsentation


PARTIE II

<web-app>
...
<servlet>
<servlet-name>tudu</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>tudu</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>

Support des annotations pour les contrleurs


Comme indiqu prcdemment, partir de la version 2.5 de Spring, la configuration des
contrleurs 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 composants par lintermdiaire des annotations dans Spring.
La premire approche consiste spcifier une implmentation de linterface
HandlerMapping fonde sur les annotations. Spring MVC propose la classe DefaultAnnotationHandlerMapping cet effet. Cette dernire peut tre utilise conjointement avec la
classe AnnotationMethodHandlerAdapter afin de configurer les mthodes de traitements des
requtes dans les contrleurs avec des annotations.
Avec cette approche, les Beans des contrleurs doivent tre configurs en tant que Beans dans
le contexte de Spring MVC.
Le code suivant dcrit lutilisation de ces deux classes dans le fichier de configuration Spring
associ la servlet DispatcherServlet de Spring MVC :
<beans (...)>
<bean class="org.springframework.web.servlet
.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet
.mvc.annotation.AnnotationMethodHandlerAdapter"/>
</beans>

La seconde consiste en lutilisation de la balise component-scan de lespace de nommage


context afin de dtecter tous les composants prsents et notamment les contrleurs Spring
MVC. 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 191 Lundi, 15. juin 2009 5:57 17

Spring MVC
CHAPITRE 7

191

La configuration de cet aspect se ralise dans le fichier de configuration Spring associ la


servlet DispatcherServlet de Spring MVC :
<beans (...)>
<context:component-scan base-package="tudu.web" />
</beans>

Il est recommand de nutiliser la premire approche que si une personnalisation de la stratgie de mappage des requtes est envisage. La seconde approche reste donc celle utiliser par
dfaut.

En rsum
Cette section a dtaill les mcanismes gnraux de fonctionnement du patron MVC de type 2
ainsi 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 et
disoler le contrleur de la vue.
Les mcanismes de chargement des contextes, de configuration du contrleur faade et de
lapproche 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 requtes


Comme nous lavons voqu prcdemment, lapproche de Spring MVC afin de traiter les
requtes est dsormais compltement dirige par des annotations. Ces dernires permettent de
configurer aussi bien laiguillage des requtes que les contrleurs eux-mmes.
Il est noter dans ce contexte que lannotation Controller permet de prciser quune classe
correspond un contrleur MVC et quelle contient les traitements correspondants.
Une fois cette annotation positionne, le mappage des URI doit tre dfini afin de slectionner
le contrleur de traitement pour une requte Web donne. Cela se configure galement par le
biais 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 de
correspondance entre la classe de traitement approprie et lURI de la requte est intgr. Le
framework configure cette correspondance en se fondant sur les informations prsentes dans
les annotations RequestMapping des contrleurs.
Afin de configurer ce mcanisme, il est indispensable de bien comprendre la structure de
lURL dune requte, qui apparat toujours sous la forme suivante dans les applications Java
EE :
http://<machine>:<port>/<alias-webapp>/<alias-ressource-web>

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

192

Les frameworks de prsentation


PARTIE II

LURI correspond la fin de lURL :


/<alias-webapp>/<alias-ressource-web>

Lalias de lapplication Web, <alias-webapp>, est configur au niveau du serveur dapplications, contrairement celui de la ressource Web, <alias-ressource-web>, qui se ralise au sein
de lapplication.
Dans un premier temps, laccs la servlet DispatcherServlet de Spring MVC est paramtr
dans le fichier web.xml du rpertoire WEB-INF afin de prendre en compte un ensemble
dURI avec des mappages de la forme *, /quelquechose/* ou *.quelquechose. Nous avons
dtaill la configuration de cet aspect la section Initialisation du contrleur faade prcdemment dans ce chapitre.
Avec les annotations, limplmentation DefaultAnnotationHandlerMapping de linterface
HandlerMapping est utilise implicitement ou explicitement suivant la configuration. Elle se
fonde sur les informations prsentes dans les annotations de type RequestMapping. Cette
dernire peut tre prsente aussi bien au niveau de la classe du contrleur que des mthodes de
ce 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 cet
aspect plus loin dans ce chapitre.
Le tableau 7-1 rcapitule les diffrentes proprits utilisables de lannotation RequestMapping.
Tableau 7-1. Proprits de lannotation RequestMapping
Proprit

Type

Description

method

String[]

Spcifie la ou les mthodes HTTP supportes par le mappage. La spcification dune


mthode 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 valeurs


dfinissant le mappage de llment. Ces valeurs peuvent ventuellement correspondre
des expressions rgulires au format Ant.

Lexemple suivant illustre lutilisation de lannotation au niveau de la classe du contrleur () afin de spcifier la valeur du mappage ainsi quau niveau de la mthode ddie
au traitement de la requte () :
@Controller
@RequestMapping("/welcome.do")
public class WelcomeController {
@RequestMapping
public void welcome() {
(...)
}
}

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

Spring MVC
CHAPITRE 7

193

Dans lexemple ci-dessus, lannotation au niveau de la mthode reprend les valeurs des
proprits de lannotation positionne au niveau de la classe.
Il est galement possible de ne spcifier le mappage quau niveau de la mthode de traitement () :
@Controller
public class WelcomeController {
@RequestMapping("/welcome.do")
public void welcome() {
(...)
}
}

Pour finir, il est galement possible de spcifier plusieurs mappages () pour une mme
annotation avec la mthode HTTP daccs souhaite () ainsi quun filtrage se fondant sur
les 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 /
<alias-webapp>/welcome.do ou /<alias-webapp>/index.do seulement par la mthode HTTP
GET si les conditions sur les paramtres sont vrifis. Dans notre cas, le paramtre auth doit
possder la valeur true, le paramtre refresh doit tre prsent, et le paramtre authenticate
ne doit pas ltre.

Les types de contrleurs


Comme indiqu prcdemment, Spring MVC fournit lannotation Controller afin de dfinir
une classe en tant que contrleur. Cette approche est particulirement flexible mettre en
uvre, car elle permet de sabstraire de lAPI Servlet et de dfinir le contenu des contrleurs
et les signatures des mthodes en fonction des besoins.
Les sections qui suivent dtaillent les diffrents mcanismes et dclinaisons utilisables afin de
mettre en uvre des contrleurs dans Spring MVC.

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

194

Les frameworks de prsentation


PARTIE II

Contrleurs de base

Pour mettre en uvre les contrleurs de ce type, lutilisation de lannotation RequestMapping


prcdemment dcrite est suffisante. Les mthodes sur lesquelles est applique cette annotation prennent en paramtres des objets de type HttpServletRequest et HttpServletResponse et
retournent un objet de type ModelAndView.
Ces contrleurs peuvent tre entres multiples puisquil est possible en standard de positionner
une annotation RequestMapping sur plusieurs de leurs mthodes.
Point dentre
Dans le contexte du pattern MVC, un point dentre correspond une mthode dun composant qui peut
tre utilise par le conteneur ou le framework qui le gre afin de traiter une requte. La signature de cette
mthode suit habituellement des conventions spcifiques afin de pouvoir tre appele.

Le code suivant illustre la mise en uvre dun contrleur simple en se fondant sur lannotation
RequestMapping () :
@Controller
public class ShowTodosController {
(...)
@RequestMapping("/showTodos.do")
public ModelAndView showTodos(HttpServletRequest request,
HttpServletResponse response) throws Exception {
Collection<TodoList> todoLists = new TreeSet<TodoList>(
userManager.getCurrentUser().getTodoLists());
String listId = null;
if (!todoLists.isEmpty()) {
listId = request.getParameter("listId");
if (listId != null) {
listId = todoLists.iterator().next().getListId());
}
}
Map<String, Object> model = new HashMap<String, Object>();
model.put("defaultList", listId);
return new ModelAndView("todos", model);
}
}

Aucune autre configuration, si ce nest linjection des dpendances avec lannotation


Autowired, nest ncessaire.
Spring MVC offre nanmoins une approche intressante et flexible afin de supporter diffrentes signatures de mthodes de traitements des contrleurs et de spcifier des mthodes de
remplissage du modle. Nous dcrivons cette approche, dont lutilisation est recommande,
aux sections suivantes.

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

Spring MVC
CHAPITRE 7

195

Support des paramtres et retours des mthodes

En parallle de la signature type pour les mthodes de traitement des contrleurs, signature
hrite des prcdentes versions de Spring MVC, le framework permet si ncessaire de
sabstraire des API Servlet et de Spring MVC. Il est en ce cas possible de spcifier une signature de mthodes en fonction de ses besoins. La dtermination des points dentre dun
contrleur est dtermine par la prsence de lannotation RequestMapping.
Il est noter que cette approche est galement valable pour les mthodes annotes par
ModelAttribute et InitBinder.
Spring MVC permet de passer directement des paramtres prcis soit par type, soit en se
fondant sur des annotations supplmentaires. Le framework permet en outre de retourner
diffrents types en fonction de ses besoins. Ces deux possibilits peuvent se combiner pour
une plus grande flexibilit.
Le tableau 7-2 rcapitule les diffrents paramtres supports par Spring MVC pour les mthodes
de 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 linter mdiaire de lAPI


Servlet.

WebRequest ou NativeWebRequest

Accs dune manire gnrique aux paramtres de la requte


sans utiliser lAPI Servlet.

Locale

Couple pays et langue associ la requte.

InputStream ou Reader

Flux dentre associ la requte afin davoir accs au contenu


de la requte.

OutputStream ou Writer

Flux de sortie associ la rponse de la requte afin de gnrer


le contenu de la rponse.

Paramtre annot par RequestParam

Paramtre de la requte dont lidentifiant est celui spcifi dans


lannotation. Spring a la responsabilit de le rcuprer dans la
requte et de le convertir dans le type attendu.

Map, Model ou ModelMap

Modle utilis pour les donnes prsentes dans la vue. Celuici offre la possibilit davoir accs aux donnes contenues dans
le 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 sur


lidentifiant spcifi dans lannotation.

Errors ou BindingResult

Rsultat du mappage et validation dobjets de formulaire. Une


validation personnalise peut se fonder sur ce paramtre afin
denregistrer les erreurs.

SessionStatus

Dans le cas dun formulaire mis en uvre sur plusieurs pages,


cet objet offre la possibilit de relcher les ressources mises en
uvre cet effet.

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

196

Les frameworks de prsentation


PARTIE II
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 est
implicitement 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 le


contenu 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 lidentifiant
de la vue utiliser. Ce mcanisme se fonde sur une implmentation de linterface
RequestToViewNameTranslator. Limplmentation par dfaut extrait cet identifiant en
enlevant 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-

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

bute

Comme le montrent ces tableaux, deux annotations sont proposes pour le traitement des
requtes, RequestParam et ModelMap. Nous dcrivons dans cette section lutilisation de la
premire et dtaillerons la seconde la section Contrleur de gestion de formulaire .
Lannotation RequestParam offre la possibilit de rfrencer un paramtre de la requte par son
nom. Lobjet correspondant est alors pass en tant que paramtre. ce niveau, une conversion
de 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 paramtre de la requte didentifiant listId par lintermdiaire dun paramtre dune mthode de
traitement du contrleur :
@Controller
public class ShowTodosController {
(...)
@RequestMapping("/showTodos.do")
public ModelAndView showTodos(
@RequestParam String listId) throws Exception {
Collection<TodoList> todoLists = new TreeSet<TodoList>(
userManager.getCurrentUser().getTodoLists());
if (!todoLists.isEmpty()) {
if (listId != null) {
listId = todoLists.iterator().next().getListId();
}
}

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

Spring MVC
CHAPITRE 7

197

Map<String, Object> model = new HashMap<String, Object>();


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

Lors de lomission de la valeur de lannotation RequestParam, le nom du paramtre sur lequel


elle porte est utilis. Ainsi, lutilisation de lannotation dans lexemple prcdent est similaire
la suivante () :
@Controller
public 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 dans


la requte. Lattribut required de lannotation permet de paramtrer ce comportement afin de
rendre 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 type


ModelMap, ce paramtre correspondant aux donnes du modle. En utilisant ce paramtre, il est
possible de manipuler les donnes du modle et den ajouter de nouvelles. Dans ce cas, il nest
plus ncessaire de retourner un objet de type ModelAndView ; une chane de caractres correspondant lidentifiant de la vue suffit.
Le code suivant illustre ladaptation de lexemple prcdent () afin dutiliser ce
mcanisme :
@Controller
public class ShowTodosController {
(...)
@RequestMapping("/showTodos.do")
public String showTodos(
@RequestParam String listId,
ModelMap model) throws Exception {
Collection<TodoList> todoLists = new TreeSet<TodoList>(
userManager.getCurrentUser().getTodoLists());

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

198

Les frameworks de prsentation


PARTIE II

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 soumission laide dannotations. Ce support se fonde sur les diffrents concepts et annotations
dcrits aux sections prcdentes.
Bien que ce type de contrleur utilise un Bean afin de stocker les informations des formulaires, aucune configuration nest raliser pour linjection de dpendances. Il suffit que ce Bean
soit prsent dans les donnes du modle et que lidentifiant correspondant soit spcifi dans le
formulaire.
La section suivante se penche sur la faon dimplmenter la gestion des formulaires HTML au
moyen de lapproche oriente annotations de Spring MVC.
Affichage du formulaire

Lutilisation des annotations RequestMapping, ModelAttribute et InitBinding permet de charger les diffrentes entits ncessaires laffichage du formulaire dans la vue. Les mthodes
sur lesquelles sont appliques ces annotations, prennent alors part au cycle de traitement de la
requte 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 requte
par le biais de la mthode GET. Le cycle denchanement des mthodes est illustr la
figure 7-4.
Spring MVC permet dinitialiser lobjet de formulaire en se fondant sur une mthode annote
par ModelAttribute. Cet objet doit tre retourn par la mthode et est automatiquement ajout
dans le modle. Il peut donc tre utilis par la suite dans la vue pour initialiser le formulaire
correspondant.
Le comportement habituel consiste crer une instance vierge chaque demande daffichage
du 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 des
valeurs de la base de donnes.

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

Spring MVC
CHAPITRE 7
Figure 7-4

199

Requte GET

Enchanement des mthodes


permettant laffichage des
donnes dun formulaire

Mthodes annotes par


ModelAttribute

Mthode annote par InitBinder

Mthode annote par


RequestMapping avec
method=RequestMethod.GET

Mthode annote par InitBinder

Vue

Le code suivant, tir de Tudu Lists, donne un exemple dutilisation de la mthode


initFormObject () 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 par
InitBinder afin de convertir les proprits du Bean de formulaire en chanes de caractres affichables dans des champs. Cette mthode doit possder un paramtre de type WebDataBinder
afin de pouvoir les enregistrer.

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

200

Les frameworks de prsentation


PARTIE II

Le code suivant indique la faon dajouter un PropertyEditor dans un contrleur de gestion de


formulaire 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 correspondante sous forme de chanes de caractres.
Il est possible dajouter des lments dans le modle par lintermdiaire de lannotation
ModelAttribute. Ces lments peuvent tre utiliss dans la construction du formulaire afin
notamment dinitialiser des listes de slection, des boutons radio ou des cases cocher. Autant
de mthodes que dlments ajouter doivent tre dfinies.
Le code suivant montre la faon dajouter les donnes ncessaires afin dinitialiser un formulaire en se fondant sur lannotation ModelAttribute () :
(...)
public class MyInfoController {
(...)
@ModelAttribute("datas")
public List<String> populateDataList() {
List<String> datas = new ArrayList<String>();
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 la
valeur RequestMethod.GET. Le mappage avec lURI peut tre spcifi ce niveau ou globalement 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 201 Lundi, 15. juin 2009 5:57 17

Spring MVC
CHAPITRE 7

201

Soumission du formulaire

Lutilisation des annotations RequestMapping, ModelAttribute et InitBinding permet de dfinir


des mthodes de remplissage de lobjet de formulaire avec les donnes soumises et de les traiter. Ces mthodes adressent des problmatiques distinctes et senchanent dans un ordre
prcis.
La soumission du formulaire est traite grce lappel dune mthode de traitement de la
requte par la mthode POST. Le cycle denchanement des mthodes est illustr la figure 7-5.
Figure 7-5

Requte POST

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

Mthode annote par InitBinder

Vue

Les premires mthodes annotes avec RequestMapping et InitBinder (respectivement


initFormObject, initBinder) fonctionnent de la mme manire que prcdemment
Une validation des donnes dun formulaire peut tre mise en uvre si ncessaire. La validation lie au mappage des donnes du formulaire dans lobjet correspondant est directement
intgre 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 est
recommand dutiliser linterface Validator afin de regrouper ces traitements. Le code de
cette 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 applique
lentit de validation. La mthode validate doit contenir limplmentation de la validation et
utiliser linstance de linterface Errors associe.

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

202

Les frameworks de prsentation


PARTIE II

Le ou les validateurs sont associs au contrleur soit par injection de dpendances, soit par
une instanciation directe, cette dernire tant peu coteuse.
Le code suivant de la classe RegisterValidator montre que limplmentation du validateur
permet de spcifier des erreurs aussi bien un niveau global () que sur chaque proprit du
formulaire () 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 avec


RequestMapping et possder la proprit method avec la valeur RequestMethod.POST. Cette
dernire prend en paramtre lobjet de formulaire, objet annot par ModelAttribute et a la
responsabilit de traiter cet objet.
Le code suivant illustre la mise en uvre dune mthode de ce type dans le cadre du contrleur
MyInfoController, mthode nomme submitForm () :
(...)
public class MyInfoController {
(...)
@RequestMapping(method = RequestMethod.POST)

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

Spring MVC
CHAPITRE 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 daffichage du formulaire en cas dchec de validation. cet effet, elle doit prendre un paramtre
de 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 soumission
du 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 Spring
offrent un support laffichage des donnes du formulaire ou des erreurs de validation. Son
utilisation est dtaille plus loin dans ce chapitre.

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

204

Les frameworks de prsentation


PARTIE II

Support des formulaires sur plusieurs pages


Spring MVC supporte la mise en uvre dun formulaire sur plusieurs pages, la session Web devant dans
ce cas tre utilise. Le framework offre la possibilit de grer implicitement le stockage de lobjet de formulaire ce niveau.
Pour ce faire, il convient de prciser que lobjet de formulaire est stock en session par lintermdiaire de
lannotation SessionAttributes au niveau de la classe du contrleur. Cette annotation permet de spcifier lidentifiant correspondant.
Pour librer les ressources associes lors dun succs de la soumission du formulaire sur la dernire page, il
convient dutiliser la mthode setComplete sur un objet de type SessionStatus. Un paramtre de ce type
peut 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 lobjet
de 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();
(...)
}
(...)
}
}

Gestion des exceptions


Par dfaut, Spring MVC fait remonter les diffrentes exceptions leves dans le conteneur de
servlets. Il est cependant possible de modifier ce comportement par lintermdiaire de linterface 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 classe


SimpleMappingExceptionResolver du package org.springframework.web.servlet.handler fournie
par le framework. Cette dernire permet de configurer les exceptions traiter ainsi que les
vues qui leur sont associes. Lexception est alors stocke dans la requte avec la cl exception,
ce qui la rend disponible pour un ventuel affichage.

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

Spring MVC
CHAPITRE 7

205

Cette implmentation se paramtre de la manire suivante :


<bean id="exceptionResolver" class="org.springframework.web
.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.springframework.dao.DataAccessException">
dataAccessFailure
</prop>
<prop key="org.springframework.transaction
.TransactionException">
dataAccessFailure
</prop>
</props>
</property>
</bean>

En rsum
Spring MVC met en uvre une approche intressante pour les contrleurs MVC fonde sur
les annotations. Elle offre ainsi la possibilit de sabstraire de lAPI Servlet en laissant le
framework raliser cette manipulation. Les signatures des points dentre des contrleurs
peuvent 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 paramtres de la requte, le remplissage du modle et la slection de la vue.

Spring MVC et la gestion de la vue


Cette section se penche sur la faon dont sont traites les vues au sein du framework Spring
MVC.

Slection de la vue et remplissage du modle


Spring MVC abstrait compltement la vue du contrleur, masquant ainsi sa technologie et sa
mise en uvre. Au niveau du contrleur, le dveloppeur a la responsabilit de remplir le
modle avec les instances utilises dans la vue et de spcifier son identifiant.
Diffrentes approches sont possibles pour cela, qui visent toutes faciliter lutilisation de
Spring et la mise en uvre des contrleurs.
La premire se fonde sur la classe ModelAndView dans le package
org.springframework.web.servlet. Les donnes vhicules par cette classe sont utilises afin
de slectionner la vue, la classe lui fournissant les donnes du modle. De ce fait, le dveloppeur ne manipule plus lAPI Servlet pour remplir le modle et passer la main aux traitements de la vue.

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

206

Les frameworks de prsentation


PARTIE II

Cette classe doit tre utilise en tant que retour dune mthode de traitement de requtes annote avec RequestMapping. Une instance de la classe ModelAndView doit alors tre instancie et
remplie ce niveau.
Les donnes du modle sont stockes sous forme de table de hachage. Le code suivant donne
un exemple de mise en uvre de ce mcanisme (), dans lequel lidentifiant todos correspond un nom symbolique de vue configur dans Spring MVC :
@RequestMapping("/showTodos.do")
public ModelAndView showTodos(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String listId = (...);
Map<String,Object> model = new HashMap<String,Object>();
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 que
paramtre dune mthode de traitement annote avec RequestMapping. Dans ce cas, ce paramtre correspond lentit de stockage des lments du modle. Lidentifiant de la vue et ces
donnes sont dsormais dissocies.
Si aucun identifiant de vue nest prcis, Spring MVC le dduit de lURI. Par exemple, si la
vue se finit par /showTodos.do, lidentifiant dduit est showTodos. Il est nanmoins possible de
spcifier explicitement lidentifiant de la vue choisie en le faisant retourner sous forme de
chane 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 dautres
lments 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 de
traitement de la requte soit appele.

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

Spring MVC
CHAPITRE 7

207

Le code suivant illustre lutilisation de lannotation ModelAttribute () afin dajouter le


retour dune mthode dans le modle et la vrification de la prsence de cet objet () dans la
mthode 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 vue
La slection des vues dans Spring MVC est effectue par le biais dune implmentation de
linterface ViewResolver dans le package org.springframework.web.servlet, comme le
montre le code suivant :
public interface ViewResolver {
View resolveViewName(String viewName, Locale locale);
}

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

Hirarchie des
implmentations de
linterface ViewResolver

AbstractCachingViewResolver

UrlBasedViewResolver

ResourceBundleViewResolver

XmlViewResolver

InternalResourceViewResolver

AbstractTemplateViewResolver

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

208

Les frameworks de prsentation


PARTIE II

ResourceBundleViewResolver

La premire implmentation, ResourceBundleViewResolver, correspond une configuration


au cas par cas des vues utilises. Cette approche est particulirement intressante pour une
utilisation des vues fondes sur diffrentes technologies de prsentation. Sa configuration
seffectue par le biais dun fichier de proprits contenant le paramtrage des diffrentes
vues.
Cette classe peut toutefois devenir vite contraignante si la majeure partie des vues utilise
la mme technologie de prsentation. Les applications qui utilisent JSP/JSTL et des vues
PDF ou Excel pour afficher des tats sont un exemple de cette contrainte. Spring MVC
offre une solution fonde sur le chanage de ViewResolver pour optimiser la rsolution de
ce problme.
Le code suivant montre de quelle manire configurer cette implmentation avec Spring MVC :
<bean id="viewResolver" class="org.springframework
.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views"/>
</bean>

La proprit basename permet de spcifier le fichier de proprits utilis, qui, dans lexemple
suivant, a pour nom views.properties :
register_ok.class=org.springframework.web.servlet.view.RedirectView
register_ok.url=welcome.action
recover_password_ok.class
=org.springframework.web.servlet.view.RedirectView
recover_password_ok.url=welcome.action
todo_lists_report.class=tudu.web.ShowTodoListsPdfView
rssFeed.class=tudu.web.RssFeedView
rssFeed.stylesheetLocation=/WEB-INF/xsl/rss.xsl

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

Les vues sont dfinies par lintermdiaire de cette implmentation au cas par cas, comme
prcdemment, mais dans un sous-contexte de Spring. Lutilisation de toutes les fonctionnalits et
mcanismes du framework est donc envisageable, de mme que linjection de dpendances
sur la classe dimplmentation des vues.
La configuration de cette implmentation se ralise de la manire suivante en utilisant par
dfaut le fichier /WEB-INF/views.xml, tout en ncartant pas la possibilit den spcifier un
autre par le biais de la proprit location :
<bean id="viewResolver"

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

Spring MVC
CHAPITRE 7

209

class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="order" value="2" />
<property name="localtion" value="/WEB-INF/views.xml" />
</bean>

InternalResourceViewResolver

Limplmentation InternalResourceViewResolver utilise les URI dans le but de rsoudre les


vues 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 par
le conteneur de servlets, telles que des servlets ou des JSP, comme dans lexemple ci-dessous :
<bean id="jspViewResolver" class="org.springframework.web
.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

Cette implmentation gnrale sapplique toutes les vues, except celles qui sont rsolues
prcdemment 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 framework
parcourt dans ce cas la chane jusqu la dcouverte du ViewResolver appropri.
Certaines de ces entits sappliquant toutes les vues, une stratgie par dfaut de rsolution
des vues peut tre dfinie. Les implmentations fondes sur UrlBasedViewResolver, telles que
InternalResourceViewResolver, fonctionnent sur ce principe.
Lutilisation des vues fondes sur JSP/JSTL peut tre spcifie. Dautres vues, comme des redirections 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 de
Tudu Lists.
Sans cette fonctionnalit, la configuration de toutes les vues au cas par cas dans un fichier
serait ncessaire, mme pour celles ne ncessitant pas de paramtrage spcifique.
Lexemple suivant dcrit la configuration du chanage de ViewResolver :
<bean id="jspViewResolver" class="org.springframework.web
.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

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

210

Les frameworks de prsentation


PARTIE II

<bean id="viewResolver"
class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="order" value="1"/>
<property name="location" value="/WEB-INF/views.xml"/>
</bean>

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

Chanage de ViewR esolver

Chanage de
ViewResolver
dans Tudu Lists

XmlViewResolver

InternalResourceViewResolver

Traitements des vues spcifies


dans la configuration du rsolveur

Traitements par dfaut des vues en


utilisant les technologies JSP /JSTL

View

JstlView

Traitements de la vue en utilisant la


technologie spcifie dans la
configuration du rsolveur

Traitements de la vue en utilisant les


technologies JSP/JSTL

Les technologies de prsentation


Spring MVC propose plusieurs fonctionnalits qui simplifient normment la mise en uvre
des technologies et frameworks de prsentation.
Dans Spring MVC, une vue correspond une implmentation de linterface View du package
org.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 package


org.springframework.web.servlet.view ou dans un de ses sous-packages.
La figure 7-8 illustre la hirarchie de ses classes et interfaces.

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

Spring MVC
CHAPITRE 7

211

Figure 7-8
View

Hirarchie des
implmentations
de linterface View

AbstractView

AbstractUrlBasedView

AbstractExcelView

AbstractJExcelView
InternalResourceView

RedirectView
AbstractPdfView

AbstractXsltView
JstlView

TilesView

Vue de redirection

Spring MVC dfinit un type de vue particulier afin de rediriger les traitements vers un URI ou
une URL par lintermdiaire de la classe RedirectView. Elle se configure avec limplmentation 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.RedirectView
register_ok.url=welcome.action

La proprit url permet de spcifier ladresse de redirection correspondante, laquelle est, dans
notre cas, relative au contexte de lapplication.
La figure 7-9 illustre lenchanement des traitements afin dutiliser une vue de type
RedirectView.
Figure 7-9

Enchanement
des traitements
pour la vue

DispatchServlet

RedirectView

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

Appelle la mthode sendRedirect sur


la requte en utilisant une proprit
url.

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

212

Les frameworks de prsentation


PARTIE II

Cette vue peut tre configure plus rapidement et directement dans la configuration des
contrleurs 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 vers
une 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.

InternalResourceView

DispatchServlet

JstlView

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

Appelle la mthode forward sur une


instance de RequestDispatcher.

Figure 7-10

Enchanement des traitements pour la vue

Le dveloppeur prend uniquement en charge le dveloppement de la page JSP, tandis que


Spring MVC a la responsabilit de mettre disposition dans la requte tout le contenu du
modle ainsi quventuellement des informations concernant le formulaire.
Les balises et expressions JSTL peuvent tre utilises dune manire classique en utilisant les
donnes du modle, ces dernires tant mises disposition par Spring MVC pour les pages
JSP. Pour une entre ayant pour cl maVariable dans le modle, la page JSP rcupre la valeur
de sa proprit maPropriete correspondante de la manire suivante :

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

Spring MVC
CHAPITRE 7

213

<c:out value="${maVariable.maPropriete}"/>

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 :
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt_rt" %>

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:
<c:forEach items="${todos}" var="todo">
- <c:out value="${todo.id}"/>, <c:out value="${todo.name}"/><br/>
</c:forEach>

Au niveau des formulaires, un taglib ddi permet de raliser le mappage entre les donnes du
formulaire et les champs correspondants. Pour pouvoir lutiliser, limportation suivante (tire
de la page WEB-INF/jspf/header.jsp) doit tre place dans les pages JSP :
<%@ taglib prefix="form"
uri="http://www.springframework.org/tags/form" %>

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 attribut du Bean de formulaire.

checkboxes

Dfinit un ensemble dlments de formulaire de type case cocher pour un attribut de formulaire. Linitialisation des valeurs des lments se ralise par tir dune liste prsente dans le
modle.

errors

Affiche les erreurs survenues lors de la soumission dun formulaire un niveau global ou par
champ.

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 partir dune liste prsente dans le modle.

password

Dfinit un lment de formulaire de type mot de passe pour un attribut 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 formulaire. 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 balise
doit tre utilise conjointement avec les balises option et options afin de spcifier les valeurs
de la liste.

textarea

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

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

214

Les frameworks de prsentation


PARTIE II

Ces balises permettent de rfrencer les attributs dun Bean de formulaire mis disposition
dans le modle laide des techniques dcrites prcdemment la section Contrleur de
gestion de formulaire .
La correspondance entre le formulaire et le Bean de formulaire se ralise au niveau de la
balise form par lintermdiaire du champ modelAttribute, qui spcifie le nom de lentre dans
le modle.
Lutilisation des balises du taglib form permet dinitialiser automatiquement les champs du
formulaire avec les donnes du formulaire et dafficher les ventuelles erreurs survenues. Le
code suivant montre lutilisation de cette balise dans la page JSP WEB-INF/jsp/user_info.jsp
de ltude de cas :
<form:form modelAttribute="userinfo">
<tr class="odd">
<td>
<fmt:message key="user.info.first.name"/>
</td>
<td>
<form:input path="firstName" size="15" maxlength="60"/>
&#160;<font color="red">
<form:errors path="firstName"/></font>
</td>
</tr>
(...)
</form:form>

La balise form permet de dfinir lidentifiant de llment dans le modle correspondant au


Bean de formulaire en se fondant sur lattribut modelAttribute (). Elle permet galement de
dlimiter les lments du formulaire.
Au sein du formulaire, les champs correspondant aux attributs du Bean de formulaire peuvent
tre spcifis. La correspondance entre le champ et lattribut correspondant se ralise par
lintermdiaire de lattribut path de la balise. Dans notre exemple, la balise input () porte
sur la proprit firstName du Bean de formulaire ayant pour nom userinfo.
Laffichage des erreurs, gnrales ou associes un champ, se ralise par lintermdiaire de la
balise 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 dans
lexemple prcdent (), lventuelle erreur correspondant au champ est affiche.
Autres vues

Spring MVC apporte des supports pour toutes sortes de vues qui ne sont pas ncessairement
fondes sur des redirections internes au conteneur de servlets (mthode forward) ou des redirections de requtes (mthode sendRedirect), notamment des classes abstraites de base pour
les technologies suivantes :
gnration de documents (PDF, Excel, etc.) ;
gnration de rapports avec Jasper Reports ;

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

Spring MVC
CHAPITRE 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, le
framework Spring MVC instancie les ressources reprsentant le document par le biais de
mthodes gnriques. Il dlgue ensuite les traitements une mthode de la vue afin de construire
le document ou de convertir le modle dans une technologie donne. Le framework reprend
ensuite en main ces traitements afin dexcuter ventuellement une transformation puis
dcrire le rsultat sur le flux de sortie.
La figure 7-11 illustre lenchanement des traitements dune vue gnrant un document avec
le support PDF de Spring MVC.

AbstractPdfView

MyView

Cration du document PDF,


initialisation du document en
utilisant les API iText

Appel de la mthode
buildPdfDocument

Construction du document
PDF

Positionnement des en-ttes


HTTP

Ecriture du document sur le


flux de sortie

Figure 7-11

Enchanement des traitements de la vue

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

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

216

Les frameworks de prsentation


PARTIE II

En rsum
Approfondissant les principes de gestion de la prsentation au sein du framework Spring
MVC, nous avons vu que ce dernier met en uvre des mcanismes de mise en relation dun
identifiant et de sa vue, tout en favorisant la coexistence de vues fondes sur diverses technologies. Le framework permet lutilisation dun nombre important de technologies de
prsentation.
La mise disposition des donnes prsentes dans le modle pour les vues est ralise automatiquement 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 les
URI conformes ce format tout en suivant le modle de programmation de Spring MVC
fond sur les annotations.
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 sur
les principes simples suivants :
LURI est trs important puisque, dans ce contexte, connatre ce dernier doit suffire pour accder la
ressource. Il nest plus besoin de spcifier des paramtres supplmentaires. De plus, la manipulation de la
ressource 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 la
responsabilit du stockage de cet tat. En parallle, la technologie utilise des standards hypermdias tels
que HTML ou XML afin de raliser les liens vers dautres ressources et dassurer ainsi la navigation dans
lapplication.
Il est possible de mettre en uvre des architectures orientes services de manire simple en utilisant
des services Web interapplicatifs. La technologie REST propose ainsi une solution de rechange intressante et plus simple au mode RPC et, dans la plupart des cas, SOAP.

Avec la technologie REST, les paramtres font partie intgrante de lURI, comme lillustre le
code suivant avec un exemple dURI contenant le paramtre id :
/<alias-webapp>/<ressource-name>/{id}

Spring 3.0 offre non seulement la possibilit dcrire des contrleurs Web REST, mais
propose 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 des
valeurs en se fondant sur lannotation PathVariable. Cette dernire fonctionne dune manire

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

Spring MVC
CHAPITRE 7

217

similaire lannotation RequestParam en rfrenant les paramtres prsents dans ladresse


daccs, 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 utilises
habituellement dans les navigateurs par les applications Web classiques, savoir les mthodes
GET et POST. Dans ce contexte, lappel dune ressource ralisant la suppression dune entit
seffectue avec la mthode DELETE. La mthode correspondante du contrleur doit spcifier
la mthode HTTP daccs au niveau de lannotation RequestMapping, comme dans le code
suivant () :
@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 du
taglib form de Spring, comme dans le code suivant () :
<form:form method="delete">
<input type="submit" value="Supprimer un todo"/></p>
</form:form>

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

Le RestTemplate
Le RestTemplate est la classe centrale du support client REST dans Spring. Il permet deffectuer des requtes HTTP selon les diffrentes mthodes du protocole, tout en facilitant la
gestion des rponses, avec la possibilit de transformer directement le flux de rponses en
objets Java.
Le RestTemplate fonctionne suivant la philosophie des templates daccs aux donnes de
Spring, dont les principes sont prsents au chapitre 10. Il peut nanmoins tre utilis directement, sans connatre ces principes sous-jacents, lessentiel consistant savoir que le

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

218

Les frameworks de prsentation


PARTIE II

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

applicatif.
Le RestTemplate peut tre instanci de faon programmatique, mais il est plus judicieux de le
dclarer dans le contexte Spring, afin de profiter de linjection de dpendances, notamment
pour de la configuration plus fine :
<bean id="restTemplate"
class="org.springframework.web.client.RestTemplate">
<property name="requestFactory">
<bean class="org.springframework.http.client.
CommonsClientHttpRequestFactory" />
</property>
</bean>

Le RestTemplate est dclar comme tout autre Bean, avec la classe correspondante (). Pour
effectuer les accs HTTP, le RestTemplate utilise une abstraction, la ClientHttpRequestFactory, que lon positionne avec la proprit requestFactory (). Nous utilisons dans notre
exemple une implmentation fonde sur la bibliothque Jakarta Commons HttpClient, qui offre
des possibilits intressantes de configuration (authentification, pool de connexions, etc.).
Une fois configur, le RestTemplate peut tre utilis pour rcuprer le rsultat dune requte
HTTP, par exemple pour appeler la mthode getTodo du contrleur REST de la section
prcdente :
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 diffrents
paramtres ; dans notre cas, le format souhait de la rponse (XML, HTML ou PDF) et lidentifiant 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), mais
nous verrons par la suite que ce mcanisme est paramtrable. Dans notre exemple, nous nous
contentons de rcuprer la rponse sous forme de chane de caractres. La mthode
getForObject accepte en derniers paramtres une liste variable dobjets, qui constituent les
paramtres insrer dans la requte HTTP ().
La combinaison de lURL demande et des paramtres fera que lURL appele sera la
suivante :
http://localhost:8080/rest/todo/xml/1

La rponse est bien sr gre par notre contrleur REST, qui renvoie pour une telle requte un
flux XML :
<todo>
<todoId>1</todoId>

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

Spring MVC
CHAPITRE 7

219

<description>todo 1</description>
<priority>1</priority>
<completed>true</completed>
<hasNotes>true</hasNotes>
</todo>

La variable locale xml dans lexemple ci-dessus contiendra donc ce code XML. Il est important de noter que lutilisation du RestTemplate nest pas limite linterrogation de contrleurs REST implments par Spring MVC. La rponse pourrait tout aussi bien tre gnre
par 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 le
RestTemplate. 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 de
notre 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. Remarquez lexistence de la mthode execute, qui, moyennant une utilisation plus complexe, permet
de construire des requtes et dexploiter les rponses pour des besoins avancs, selon le principe des templates Spring.
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 )

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

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

220

Les frameworks de prsentation


PARTIE II

Le RestTemplate propose un mcanisme de convertisseur qui permet de contrler trs finement la conversion des objets Java qui lui sont passs ainsi que ceux quil renvoie. Nous allons
ici nous intresser aux objets renvoys, en convertissant le flux XML reu prcdemment en
un objet Todo.
Cette conversion nous permettra deffectuer lappel suivant, pour lequel nous demandons et
rcuprons 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 la


conversion 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<Todo> {
public List<MediaType> getSupportedMediaTypes() {
return Collections.singletonList(
new MediaType("text","xml")
);
}
public boolean supports(Class<? extends Todo> clazz) {
return Todo.class.equals(clazz);
}
public Todo read(Class<Todo> clazz,
HttpInputMessage inputMessage)
throws IOException {
XStream xstream = new XStream();
xstream.alias("todo", Todo.class);
return (Todo) xstream.fromXML(inputMessage.getBody());
}
public void write(Todo t, HttpOutputMessage outputMessage)
throws IOException {
throw new UnsupportedOperationException();
}
}

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

Spring MVC
CHAPITRE 7

221

Le rle dun HttpMessageConverter est deffectuer des transformations dobjets Java vers des
messages HTTP et inversement. Il doit donc indiquer le type de mdia quil est capable de
grer () : dans notre cas les rponses de type text/xml, ainsi que la hirarchie de classes
quil peut convertir (), cest--dire des Todos.
La mthode read nous intresse particulirement, car cest elle qui se charge de la transformation de la rponse en Todo. Nous recevons ici une reprsentation XML dun Todo, et nous utilisons XStream pour la convertir en objet Java (). XStream prsente lintrt dtre trs
simple dutilisation et concis, mais tout autre mcanisme de dsrialisation aurait pu tout aussi
bien 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 :
<bean id="restTemplate"
class="org.springframework.web.client.RestTemplate">
(...)
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.
ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.
StringHttpMessageConverter"/>
<bean class="tudu.web.rest.TodoHttpMessageConverter" />
</list>
</property>
</bean>

Un RestTemplate dispose de convertisseurs positionns par dfaut, qui grent les conversions sous forme de chanes de caractres ou de tableau doctets. Il faut les positionner
explicitement ds que nous paramtrons la proprit messageConverters, afin que ces cas
simples soient toujours grs (). Notre convertisseur de Todo est lui paramtr au
repre .
Le mcanisme de convertisseurs apporte au RestTemplate une extensibilit et une adaptabilit
trs intressantes, lui permettant de grer la conversion des messages HTTP en objets Java,
afin dobtenir un code applicatif le plus pur possible.

En rsum
Spring 3.0 apporte un support REST Spring MVC. Il devient alors possible dimplmenter
des contrleurs REST en suivant le modle de programmation de Spring MVC, fond sur les
annotations.
Le support client nest pas en reste, avec le RestTemplate, qui propose une API trs simple et
extensible afin dinterroger des services REST (indpendamment de leur technologie) et
dexploiter au mieux leur rponse.

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

222

Les frameworks de prsentation


PARTIE II

Mise en uvre de Spring MVC dans Tudu Lists


Les principaux concepts et composants de Spring MVC ayant t introduits, nous pouvons
passer leur mise en pratique dans notre tude de cas.

Configuration des contextes


Le premier contexte renvoie lapplication Web. Il est charg avec le support de la classe
ContextLoaderListener 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 DispatcherServlet
en utilisant le fichier action-servlet.xml localis dans le rpertoire WEB-INF. Les diffrentes
entits relatives Spring MVC sont dfinies dans ce fichier.
Cette servlet est configure dans le fichier web.xml de lapplication Web, comme lillustre le
code suivant :
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
(...)
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
(...)
</web-app>

Dans le fichier action-servlet.xml suivant, lapproche fonde sur les annotations a t active
en se fondant sur la balise component-scan () de lespace de nommage context (seuls les
contrleurs localiss dans les packages dont le nom commence par tudu.web tant utiliss) :
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/
context/spring-context.xsd">
<context:component-scan base-package="tudu.web" />
(...)
</beans>

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

Spring MVC
CHAPITRE 7

223

Commons Validator

Le projet Spring Modules offre le support de Commons Validator, le framework dApache


visant 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 :
<bean id="validatorFactory" class="org.springmodules.commons
.validator.DefaultValidatorFactory">
<property name="validationConfigLocations">
<list>
<value>/WEB-INF/validator-rules.xml</value>
<value>/WEB-INF/validation.xml</value>
</list>
</property>
</bean>
<bean id="beanValidator" class="org.springmodules.commons
.validator.DefaultBeanValidator">
<property name="validatorFactory" ref="validatorFactory"/>
</bean>

Dans chaque contrleur de gestion de formulaire, le Bean beanValidator doit tre inject par
lintermdiaire de lannotation Autowired. Le nom du Bean de formulaire utilis par le contrleur
permet de dterminer la rgle utiliser de la configuration de la validation WEB-INF/validation.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 sont
implments par le biais des annotations RequestMapping, ModelAttribute et InitBinder dcrites 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 une
gestion de formulaire HTML. La prsentation associe ces deux contrleurs utilise les technologies JSP/JSTL.
Contrleur simple

Le contrleur ShowTodosAction du package tudu.web dispose de traitements pour afficher les


todos dune liste. Comme lillustre lextrait de code ci-aprs, il utilise Spring MVC laide
des lments suivants :
Annotation Controller au niveau de la classe () afin de prciser que cette dernire joue le
rle dun contrleur dans Spring MVC.
Annotation RequestMapping au niveau de la mthode showTodos () afin de dfinir le point
dentre. Plusieurs points dentre peuvent tre spcifis ce niveau.

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

224

Les frameworks de prsentation


PARTIE II

Annotation RequestParam afin de rcuprer directement en tant que paramtres du point


dentre 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 vaut
null.
Paramtre de type ModelMap () afin de manipuler les donnes du modle. Des ajouts dans
ce 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 ( ).
@Controller
public class ShowTodosController {
(...)
@RequestMapping("/secure/showTodos.action")
public String showTodos(
@RequestParam(value="listId",
required=false) String listId,
ModelMap model
) {
log.debug("Execute show action");
Collection<TodoList> todoLists = new TreeSet<TodoList>(
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 le


contrleur. Les configurations relatives Spring MVC () et linjection de dpendances
() se ralise directement dans la classe par lintermdiaire dannotations, comme lillustre
le code suivant :
@Controller
public class ShowTodosController {
@Autowired
private UserManager userManager;
(...)
@RequestMapping("/secure/showTodos.action")
public String showTodos(

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

Spring MVC
CHAPITRE 7

225

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

La manire daccder aux points dentre du contrleur est dfinie dans les annotations
RequestMapping. Aucune configuration supplmentaire nest ncessaire. Dans le cas prcdent, le
contrleur 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 de
plusieurs ViewResolver :
Le premier est implment par la classe ResourceBundleViewResolver, qui utilise le fichier
de proprits views.properties afin de configurer les vues.
Le deuxime est implment par la classe XmlViewResolver, qui utilise le fichier /WEBINF/views.xml pour configurer les vues.
Le dernier est implment par la classe InternalResourceViewResolver, qui se fonde, dans
notre cas, sur une vue JSP/JSTL. Il constitue la stratgie de rsolution par dfaut et est
utilis dans le cas o un identifiant de vue ne peut tre rsolu par les deux entits prcdemment dcrites.
La figure 7-12 illustre cette chane en soulignant les identifiants des vues configures dans les
deux premiers ViewResolver.
ViewResolver1
(views.properties)

ViewResolver2
(views.xml)

ViewResolver3
(JSP / JSTL)

Vues : register_ok,
recover_password_ok,
rssFeed

Vues : todol_lists_report,
backup

Vues : toutes les pages JSP

Figure 7-12

Chanage des ViewResolver dans Tudu Lists

Le contrleur utilise la vue todos qui est rsolue par le dernier ViewResolver et correspond
donc 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 que
celle dun contrleur simple : un Bean est utilis pour les donnes du formulaire, et deux
points dentre doivent tre dfinis, un pour le chargement du formulaire, lautre pour sa validation.

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

226

Les frameworks de prsentation


PARTIE II

Dtaillons le contrleur MyInfosController du package tudu.web, qui permet de modifier les


informations dun utilisateur de lapplication.
Comme lillustre lextrait de code ci-aprs, ce contrleur utilise Spring MVC laide des
lments suivants :
Annotations Controller et RequestMapping au niveau de la classe afin de dfinir la classe en
tant que contrleur et lURI daccs ce dernier ().
Mthode showForm () appele par lintermdiaire dune mthode GET et configure avec
lannotation RequestMapping. Cette mthode a la responsabilit de charger les donnes du
formulaire.
Mthode submitForm () appele afin de traiter les donnes soumises par le formulaire
avec la mthode HTTP POST et configure avec lannotation RequestMapping.
Utilisation explicite de la validation Commons Validator dans le corps de la mthode
submitForm ().
Spcification des vues utilises pour laffichage suite la soumission du formulaire par
lintermdiaire 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(
HttpServletRequest request,
@ModelAttribute("userinfo") UserInfoData userInfo,
BindingResult result) {
beanValidator.validate(userInfo, result);
if (!result.hasErrors()) {
String password = userInfo.getPassword();
String firstName = userInfo.getFirstName();
String lastName = userInfo.getLastName();

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

Spring MVC
CHAPITRE 7

227

String email = userInfo.getEmail();


String login = request.getRemoteUser();
User user = userManager.findUser(login);
user.setPassword(password);
user.setFirstName(firstName);
user.setLastName(lastName);
user.setEmail(email);
userManager.updateUser(user);
}
return "userinfo";
}
}

Aucune configuration nest requise dans le fichier WEB-INF/action-servlet.xml pour le


contrleur. Comme le montre le code suivant, les configurations relatives Spring MVC ()
et linjection de dpendances () se ralisent directement dans la classe par lintermdiaire
dannotations :
@Controller
public class MyInfoController {
@Autowired
private UserManager userManager;
@Autowired
private DefaultBeanValidator beanValidator;
(...)
@RequestMapping(method = RequestMethod.GET)
public String showForm(HttpServletRequest request,
ModelMap model) {
(...)
}
@RequestMapping(method=RequestMethod.POST)
public String submitForm(
HttpServletRequest request,
@ModelAttribute("userinfo") UserInfoData userInfo,
BindingResult result) {
(...)
}
}

La manire daccder aux points dentre du contrleur est dfinie dans les annotations
RequestMapping. Aucune configuration supplmentaire nest ncessaire. Dans lexemple
prcdent, le contrleur MyInfoController est accessible partir de lURI /secure/
myinfos.action par lintermdiaire des mthodes GET et POST.

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

228

Les frameworks de prsentation


PARTIE II

Les donnes du formulaire soumises peuvent tre valides par le biais de labstraction
Validator vue prcdemment, et plus particulirement les implmentations constituant le
support de Commons Validator, qui permet de rutiliser les rgles de validation userinfo.
Le contrleur utilise la vue user_info dans le but dafficher le formulaire dans les cas dchec
ou de succs lors de la validation. Cette vue est rsolue par le dernier ViewResolver de la
chane et correspond donc la page JSP user_info.jsp localise dans le rpertoire /WEBINF/jsp/. Cette page doit tre modifie afin de remplacer les taglibs de gestion des formulaires de
Struts par ceux de Spring MVC.
Comme lillustre le code suivant, le framework met en uvre le taglib form afin de remplir les
champs du formulaire () et dafficher les ventuelles erreurs de validation () :
(...)
<form:form modelAttribute="userinfo" focus="firstName">
<font color="red">
<b><form:errors path="*"/></b>
</font>
(...)
<form:input path="firstName" size="15" maxlength="60"/>
&#160;<font color="red">
<form:errors path="firstName"/></font>
(...)
<input type="submit" value="<fmt:message key="form.submit"/>"/>
<input type="button"
onclick="document.location.href='<c:url
value="../welcome.action"/>';"
value="<fmt:message key="form.cancel"/>"/>
</form>

Le contrleur affiche la page de formulaire suite au succs de la soumission des donnes par
lappel de la mthode showForm dans la mthode onSubmit. Lutilisation dune autre vue grce
aux mthodes setSuccessView et getSuccessView serait aussi possible.

Implmentation de vues spcifiques


Tudu Lists utilise plusieurs technologies de prsentation afin de gnrer diffrents formats de
sortie (HTML, XML, RSS, PDF). Spring MVC offre une infrastructure facilitant leur utilisation
conjointement dans une mme application.
Dans la mesure o lentit ViewResolver utilise prcdemment pour les vues utilise les technologies JSP et JSTL, elle ne peut servir pour les vues dcrites ci-dessous. Dans les sections
suivantes, nous utiliserons donc limplmentation XmlViewResolver afin de les configurer.
XML

Lapplication Tudu Lists permet de sauvegarder au format XML les informations contenues
dans une liste de todos. Cette fonctionnalit est implmente par le contrleur BackupTodoListController du package tudu.web, qui a la responsabilit de charger la liste correspondant

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

Spring MVC
CHAPITRE 7

229

lidentifiant spcifi puis de la placer dans le modle afin de la rendre disponible lors de la
construction de la vue.
Ce contrleur dirige les traitements vers la vue ayant pour identifiant backup la fin de ses
traitements. Cette vue, implmente par la classe BackupTodoListView du package tudu.web,
est rsolue par le second ViewResolver de la chane.
Sa configuration se trouve dans le fichier views.xml localis dans le rpertoire WEB-INF.
Elle utilise le support de la classe AbstractXsltView de Spring MVC afin de gnrer une sortie
XML, comme dans le code suivant :
public class BackupTodoListView extends AbstractXsltView {
(...)
protected Node createDomNode(Map model,
String rootName, HttpServletRequest request,
HttpServletResponse response) throws Exception {
TodoList todoList = (TodoList)model.get("todoList");
Document doc = todoListsManager.backupTodoList(todoList);
return new DOMOutputter().output( doc );
}
}

la fin de lexcution de la mthode createDomNode, la classe BackupTodoListView rend la


main sa classe mre afin de raliser ventuellement une transformation XSLT et dcrire le
contenu sur le flux de sortie.
Lutilisation de XmlViewResolver permet dinjecter une instance du composant TodoListsManager dans la classe de la vue, comme dcrit dans le fichier views.xml suivant :
<bean id="backup" class="tudu.web.BackupTodoListView">
<property name="todoListsManager" ref="todoListsManager"/>
</bean>

PDF

Lapplication de ltude de cas permet galement de gnrer un rapport au format PDF avec
les informations contenues dans une liste de todos. Cette fonctionnalit est implmente par
lintermdiaire du contrleur ShowTodoListsReportController du package tudu.web, qui a la
responsabilit de charger la liste correspondant lidentifiant spcifi puis de la placer dans le
modle afin de la rendre disponible lors de la construction de la vue.
Ce contrleur dirige les traitements vers la vue ayant pour identifiant todo_lists_report la
fin de ses traitements. Cette vue, implmente par la classe ShowTodoListsPdfView du package
tudu.web, est rsolue par le second ViewResolver de la chane.
Sa configuration se trouve dans le fichier views.xml localis dans le rpertoire WEB-INF.
Elle utilise le support de la classe AbstractPdfView de Spring MVC afin de gnrer une sortie
PDF par le biais du framework iText, comme dans le code suivant :
public class ShowTodoListsPdfView extends AbstractPdfView {
protected void buildPdfDocument(

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

230

Les frameworks de prsentation


PARTIE II

Map model, Document doc,


PdfWriter writer, HttpServletRequest req,
HttpServletResponse resp) throws Exception {
TodoList todoList=(TodoList)model.get("todolist");
doc.add(new Paragraph(todoList.getListId()));
doc.add(new Paragraph(todoList.getName()));
(...)
}
}

La classe mre de la classe ShowTodoListsPdfView a la responsabilit dinstancier les diffrentes classes de iText afin de les lui fournir. la fin de lexcution de la mthode
buildPdfDocument, la classe ShowTodoListsPdfView rend la main sa classe mre pour crire le
contenu sur le flux de sortie.
Notons que cette vue aurait pu aussi bien tre configure dans le fichier views.properties,
puisquelle ne ncessite pas dinjection de dpendances.

Conclusion
Pour mettre en uvre le patron de conception MVC, Spring MVC offre une approche intressante fonde sur les mcanismes dinjection de dpendances et les mtadonnes configures
dans des annotations.
Les principaux atouts du framework rsident dans son ouverture ainsi que dans la modularit
et lisolation des composants du patron MVC. Le dveloppement des applications utilisant
diffrentes technologies sen trouve facilit, et le changement de briques nimpacte pas le
reste de lapplication ni lextension du framework.
Lutilisation de linjection de dpendances de Spring dans limplmentation du pattern MVC
permet de configurer avec une relle facilit ces diffrents composants ainsi que leurs dpendances. Cette configuration est centralise dans le contexte applicatif de Spring, lequel peut de
la sorte mettre disposition toute la puissance du conteneur lger.
Spring MVC propose une approche fonde sur les annotations afin dimplmenter les contrleurs. Introduite avec la version 2.5 du framework, cette approche dune grande facilit
dutilisation permet de sabstraire de lAPI Servlet. Le framework propose ainsi une gestion
des formulaires dune flexibilit remarquable.
Le framework Spring MVC propose enfin une sparation claire entre le contrleur et la vue
ainsi quun support pour les diffrentes technologies et frameworks de prsentation.
En rsum, ce framework fournit un socle solide pour dvelopper des applications Web sans
donner la possibilit dabstraire la navigation et lenchanement des pages. Un framework tel
que Spring Web Flow, prsent en dtail au chapitre suivant, peut sappuyer sur ce socle afin
de rsoudre cette problmatique.

Вам также может понравиться